@dxos/plugin-space 0.7.4 → 0.7.5-feature-compute.4d9d99a
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/app-graph-builder-5D2QB43K.mjs +365 -0
- package/dist/lib/browser/app-graph-builder-5D2QB43K.mjs.map +7 -0
- package/dist/lib/browser/app-graph-serializer-VNWPLPDF.mjs +80 -0
- package/dist/lib/browser/app-graph-serializer-VNWPLPDF.mjs.map +7 -0
- package/dist/lib/browser/chunk-5TBRONF6.mjs +133 -0
- package/dist/lib/browser/chunk-5TBRONF6.mjs.map +7 -0
- package/dist/lib/browser/chunk-6SWQRWOD.mjs +1672 -0
- package/dist/lib/browser/chunk-6SWQRWOD.mjs.map +7 -0
- package/dist/lib/browser/chunk-HCXWKGTE.mjs +316 -0
- package/dist/lib/browser/chunk-HCXWKGTE.mjs.map +7 -0
- package/dist/lib/browser/chunk-SOXNANA6.mjs +12 -0
- package/dist/lib/browser/chunk-SOXNANA6.mjs.map +7 -0
- package/dist/lib/browser/chunk-UH5P4UL3.mjs +21 -0
- package/dist/lib/browser/chunk-UH5P4UL3.mjs.map +7 -0
- package/dist/lib/browser/chunk-ZBKFJNHH.mjs +523 -0
- package/dist/lib/browser/chunk-ZBKFJNHH.mjs.map +7 -0
- package/dist/lib/browser/identity-created-EC5FOCX2.mjs +28 -0
- package/dist/lib/browser/identity-created-EC5FOCX2.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +192 -3521
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-VBL572N7.mjs +459 -0
- package/dist/lib/browser/intent-resolver-VBL572N7.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-root-AZJFNTKK.mjs +28 -0
- package/dist/lib/browser/react-root-AZJFNTKK.mjs.map +7 -0
- package/dist/lib/browser/react-surface-E2VSYVNZ.mjs +238 -0
- package/dist/lib/browser/react-surface-E2VSYVNZ.mjs.map +7 -0
- package/dist/lib/browser/settings-ASFF5BZL.mjs +24 -0
- package/dist/lib/browser/settings-ASFF5BZL.mjs.map +7 -0
- package/dist/lib/browser/spaces-ready-4SFNS5JQ.mjs +200 -0
- package/dist/lib/browser/spaces-ready-4SFNS5JQ.mjs.map +7 -0
- package/dist/lib/browser/state-MS4KYJWI.mjs +47 -0
- package/dist/lib/browser/state-MS4KYJWI.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +14 -5
- package/dist/lib/node/app-graph-builder-ZQ5S62YR.cjs +368 -0
- package/dist/lib/node/app-graph-builder-ZQ5S62YR.cjs.map +7 -0
- package/dist/lib/node/app-graph-serializer-72S7P33H.cjs +88 -0
- package/dist/lib/node/app-graph-serializer-72S7P33H.cjs.map +7 -0
- package/dist/lib/node/chunk-56NGXG2A.cjs +41 -0
- package/dist/lib/node/chunk-56NGXG2A.cjs.map +7 -0
- package/dist/lib/node/{meta.cjs → chunk-AO4EW2RX.cjs} +12 -13
- package/dist/lib/node/chunk-AO4EW2RX.cjs.map +7 -0
- package/dist/lib/node/chunk-BQRNTKSQ.cjs +150 -0
- package/dist/lib/node/chunk-BQRNTKSQ.cjs.map +7 -0
- package/dist/lib/node/chunk-DDZYVNVP.cjs +345 -0
- package/dist/lib/node/chunk-DDZYVNVP.cjs.map +7 -0
- package/dist/lib/node/chunk-M64YG2FY.cjs +1669 -0
- package/dist/lib/node/chunk-M64YG2FY.cjs.map +7 -0
- package/dist/lib/node/chunk-Z34MTEU7.cjs +551 -0
- package/dist/lib/node/chunk-Z34MTEU7.cjs.map +7 -0
- package/dist/lib/node/identity-created-IMDS4A6A.cjs +44 -0
- package/dist/lib/node/identity-created-IMDS4A6A.cjs.map +7 -0
- package/dist/lib/node/index.cjs +175 -3506
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/intent-resolver-S4HZABYI.cjs +458 -0
- package/dist/lib/node/intent-resolver-S4HZABYI.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/react-root-RB3OM3QG.cjs +50 -0
- package/dist/lib/node/react-root-RB3OM3QG.cjs.map +7 -0
- package/dist/lib/node/react-surface-TLKQEHHT.cjs +233 -0
- package/dist/lib/node/react-surface-TLKQEHHT.cjs.map +7 -0
- package/dist/lib/node/settings-QLCKAUHK.cjs +38 -0
- package/dist/lib/node/settings-QLCKAUHK.cjs.map +7 -0
- package/dist/lib/node/spaces-ready-RZTKEXOL.cjs +211 -0
- package/dist/lib/node/spaces-ready-RZTKEXOL.cjs.map +7 -0
- package/dist/lib/node/state-4UIOUKLJ.cjs +61 -0
- package/dist/lib/node/state-4UIOUKLJ.cjs.map +7 -0
- package/dist/lib/node/types/index.cjs +23 -14
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/app-graph-builder-CD6IYPSS.mjs +366 -0
- package/dist/lib/node-esm/app-graph-builder-CD6IYPSS.mjs.map +7 -0
- package/dist/lib/node-esm/app-graph-serializer-CFXS6ZE2.mjs +81 -0
- package/dist/lib/node-esm/app-graph-serializer-CFXS6ZE2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-375RB3CZ.mjs +22 -0
- package/dist/lib/node-esm/chunk-375RB3CZ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7FUVU45N.mjs +14 -0
- package/dist/lib/node-esm/chunk-7FUVU45N.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CLGCKZ2D.mjs +317 -0
- package/dist/lib/node-esm/chunk-CLGCKZ2D.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CMKML5IN.mjs +1673 -0
- package/dist/lib/node-esm/chunk-CMKML5IN.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-FUMGYUD3.mjs +524 -0
- package/dist/lib/node-esm/chunk-FUMGYUD3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-M4XTHK35.mjs +134 -0
- package/dist/lib/node-esm/chunk-M4XTHK35.mjs.map +7 -0
- package/dist/lib/node-esm/identity-created-SJYZZ7Q3.mjs +29 -0
- package/dist/lib/node-esm/identity-created-SJYZZ7Q3.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +192 -3521
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/intent-resolver-OIQH7HN7.mjs +460 -0
- package/dist/lib/node-esm/intent-resolver-OIQH7HN7.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/react-root-WKJWCHXR.mjs +29 -0
- package/dist/lib/node-esm/react-root-WKJWCHXR.mjs.map +7 -0
- package/dist/lib/node-esm/react-surface-RVEHOSAD.mjs +239 -0
- package/dist/lib/node-esm/react-surface-RVEHOSAD.mjs.map +7 -0
- package/dist/lib/node-esm/settings-WLVEO4JM.mjs +25 -0
- package/dist/lib/node-esm/settings-WLVEO4JM.mjs.map +7 -0
- package/dist/lib/node-esm/spaces-ready-ITGYYT5A.mjs +201 -0
- package/dist/lib/node-esm/spaces-ready-ITGYYT5A.mjs.map +7 -0
- package/dist/lib/node-esm/state-BMISGQ2O.mjs +48 -0
- package/dist/lib/node-esm/state-BMISGQ2O.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +14 -5
- package/dist/types/src/SpacePlugin.d.ts +1 -24
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-serializer.d.ts +4 -0
- package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +15 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
- package/dist/types/src/capabilities/identity-created.d.ts +4 -0
- package/dist/types/src/capabilities/identity-created.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +195 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts +8 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-root.d.ts +7 -0
- package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +7 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings.d.ts +4 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/capabilities/spaces-ready.d.ts +4 -0
- package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +5 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts +7 -0
- package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts.map +1 -0
- package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts +8 -0
- package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts.map +1 -0
- package/dist/types/src/components/AdvancedObjectSettings/index.d.ts +2 -0
- package/dist/types/src/components/AdvancedObjectSettings/index.d.ts.map +1 -0
- package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
- package/dist/types/src/components/BaseObjectSettings.d.ts +7 -0
- package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -0
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +5 -4
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +5 -6
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +1 -0
- package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
- package/dist/types/src/components/JoinDialog.d.ts +1 -0
- package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
- package/dist/types/src/components/PopoverRenameObject.d.ts +1 -0
- package/dist/types/src/components/PopoverRenameObject.d.ts.map +1 -1
- package/dist/types/src/components/PopoverRenameSpace.d.ts +1 -0
- package/dist/types/src/components/PopoverRenameSpace.d.ts.map +1 -1
- package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
- package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
- package/dist/types/src/components/SpacePresence.d.ts +9 -6
- package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
- package/dist/types/src/components/SpacePresence.stories.d.ts +1 -1
- package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +1 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +4 -3
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +3 -3
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts +2 -2
- package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +5 -0
- package/dist/types/src/events.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/usePath.d.ts +11 -0
- package/dist/types/src/hooks/usePath.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -27
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +18 -3
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/collection.d.ts +8 -12
- package/dist/types/src/types/collection.d.ts.map +1 -1
- package/dist/types/src/types/thread.d.ts +180 -186
- package/dist/types/src/types/thread.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +228 -16
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +9 -8
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +38 -46
- package/src/SpacePlugin.tsx +119 -1541
- package/src/capabilities/app-graph-builder.ts +392 -0
- package/src/capabilities/app-graph-serializer.ts +73 -0
- package/src/capabilities/capabilities.ts +23 -0
- package/src/capabilities/identity-created.ts +26 -0
- package/src/capabilities/index.ts +17 -0
- package/src/capabilities/intent-resolver.ts +420 -0
- package/src/capabilities/react-root.tsx +20 -0
- package/src/capabilities/react-surface.tsx +234 -0
- package/src/capabilities/settings.ts +17 -0
- package/src/capabilities/spaces-ready.ts +231 -0
- package/src/capabilities/state.ts +45 -0
- package/src/components/AdvancedObjectSettings/AdvancedObjectSettings.tsx +72 -0
- package/src/components/AdvancedObjectSettings/ForeignKeys.tsx +51 -0
- package/src/components/AdvancedObjectSettings/index.ts +5 -0
- package/src/components/AwaitingObject.tsx +15 -19
- package/src/components/{DefaultObjectSettings.tsx → BaseObjectSettings.tsx} +2 -2
- package/src/components/CreateDialog/CreateObjectDialog.tsx +36 -25
- package/src/components/CreateDialog/CreateObjectPanel.tsx +61 -24
- package/src/components/CreateDialog/CreateSpaceDialog.tsx +10 -14
- package/src/components/JoinDialog.tsx +18 -34
- package/src/components/PersistenceStatus.tsx +1 -1
- package/src/components/PopoverRenameObject.tsx +2 -0
- package/src/components/PopoverRenameSpace.tsx +2 -0
- package/src/components/ShareSpaceButton.tsx +5 -4
- package/src/components/SpacePluginSettings.tsx +2 -13
- package/src/components/SpacePresence.stories.tsx +25 -17
- package/src/components/SpacePresence.tsx +42 -21
- package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +2 -3
- package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +3 -1
- package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +7 -5
- package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +6 -5
- package/src/components/SyncStatus/InlineSyncStatus.tsx +37 -27
- package/src/components/SyncStatus/SyncStatusDetail.stories.tsx +55 -51
- package/src/components/index.ts +2 -1
- package/src/events.ts +12 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/usePath.ts +44 -0
- package/src/index.ts +3 -7
- package/src/meta.ts +1 -29
- package/src/translations.ts +7 -2
- package/src/types/collection.ts +3 -3
- package/src/types/thread.ts +6 -6
- package/src/types/types.ts +177 -42
- package/src/util.tsx +77 -64
- package/dist/lib/browser/chunk-FTKV32QZ.mjs +0 -43
- package/dist/lib/browser/chunk-FTKV32QZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-MWKXNS5S.mjs +0 -124
- package/dist/lib/browser/chunk-MWKXNS5S.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -15
- package/dist/lib/browser/meta.mjs.map +0 -7
- package/dist/lib/node/chunk-6SNOZF7Y.cjs +0 -152
- package/dist/lib/node/chunk-6SNOZF7Y.cjs.map +0 -7
- package/dist/lib/node/chunk-QNVEU2UD.cjs +0 -69
- package/dist/lib/node/chunk-QNVEU2UD.cjs.map +0 -7
- package/dist/lib/node/meta.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-OHEAWSCA.mjs +0 -126
- package/dist/lib/node-esm/chunk-OHEAWSCA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UMV7XREB.mjs +0 -45
- package/dist/lib/node-esm/chunk-UMV7XREB.mjs.map +0 -7
- package/dist/lib/node-esm/meta.mjs +0 -16
- package/dist/lib/node-esm/meta.mjs.map +0 -7
- package/dist/types/src/components/DefaultObjectSettings.d.ts +0 -7
- package/dist/types/src/components/DefaultObjectSettings.d.ts.map +0 -1
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts +0 -6
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts.map +0 -1
- package/src/components/SyncStatus/InlineSyncStatus.stories.tsx +0 -57
package/src/SpacePlugin.tsx
CHANGED
|
@@ -1,123 +1,38 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { signal } from '@preact/signals-core';
|
|
6
|
-
import React from 'react';
|
|
7
|
-
|
|
8
5
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
type Plugin,
|
|
18
|
-
type PluginDefinition,
|
|
19
|
-
Surface,
|
|
20
|
-
filterPlugins,
|
|
21
|
-
findPlugin,
|
|
22
|
-
firstIdInPart,
|
|
23
|
-
openIds,
|
|
24
|
-
parseGraphPlugin,
|
|
25
|
-
parseIntentPlugin,
|
|
26
|
-
parseLayoutPlugin,
|
|
27
|
-
parseMetadataResolverPlugin,
|
|
28
|
-
parseNavigationPlugin,
|
|
29
|
-
resolvePlugin,
|
|
6
|
+
allOf,
|
|
7
|
+
Capabilities,
|
|
8
|
+
contributes,
|
|
9
|
+
createIntent,
|
|
10
|
+
defineModule,
|
|
11
|
+
definePlugin,
|
|
12
|
+
Events,
|
|
13
|
+
oneOf,
|
|
30
14
|
} from '@dxos/app-framework';
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import { LocalStorageStore } from '@dxos/local-storage';
|
|
37
|
-
import { log } from '@dxos/log';
|
|
38
|
-
import { Migrations } from '@dxos/migrations';
|
|
39
|
-
import { type AttentionPluginProvides, parseAttentionPlugin } from '@dxos/plugin-attention';
|
|
40
|
-
import { type ClientPluginProvides, parseClientPlugin } from '@dxos/plugin-client';
|
|
41
|
-
import { type Node, createExtension, memoize, toSignal } from '@dxos/plugin-graph';
|
|
42
|
-
import { ObservabilityAction } from '@dxos/plugin-observability/meta';
|
|
43
|
-
import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
44
|
-
import { type Client, PublicKey } from '@dxos/react-client';
|
|
45
|
-
import {
|
|
46
|
-
Expando,
|
|
47
|
-
FQ_ID_LENGTH,
|
|
48
|
-
Filter,
|
|
49
|
-
OBJECT_ID_LENGTH,
|
|
50
|
-
type ReactiveEchoObject,
|
|
51
|
-
SPACE_ID_LENGTH,
|
|
52
|
-
type Space,
|
|
53
|
-
SpaceState,
|
|
54
|
-
fullyQualifiedId,
|
|
55
|
-
getSpace,
|
|
56
|
-
getTypename,
|
|
57
|
-
isEchoObject,
|
|
58
|
-
isSpace,
|
|
59
|
-
loadObjectReferences,
|
|
60
|
-
parseFullyQualifiedId,
|
|
61
|
-
parseId,
|
|
62
|
-
} from '@dxos/react-client/echo';
|
|
63
|
-
import { type JoinPanelProps, osTranslations } from '@dxos/shell/react';
|
|
64
|
-
import { ComplexMap, nonNullable, reduceGroupBy } from '@dxos/util';
|
|
15
|
+
import { RefArray } from '@dxos/live-object';
|
|
16
|
+
import { AttentionEvents } from '@dxos/plugin-attention';
|
|
17
|
+
import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
|
|
18
|
+
import { DeckCapabilities } from '@dxos/plugin-deck';
|
|
19
|
+
import { osTranslations } from '@dxos/shell/react';
|
|
65
20
|
|
|
66
21
|
import {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
ShareSpaceButton,
|
|
80
|
-
SmallPresence,
|
|
81
|
-
SmallPresenceLive,
|
|
82
|
-
SpacePluginSettings,
|
|
83
|
-
SpacePresence,
|
|
84
|
-
SpaceSettingsDialog,
|
|
85
|
-
SpaceSettingsPanel,
|
|
86
|
-
SyncStatus,
|
|
87
|
-
type SpaceSettingsDialogProps,
|
|
88
|
-
} from './components';
|
|
89
|
-
import meta, { CollectionAction, SPACE_PLUGIN, SpaceAction } from './meta';
|
|
22
|
+
AppGraphBuilder,
|
|
23
|
+
AppGraphSerializer,
|
|
24
|
+
IdentityCreated,
|
|
25
|
+
IntentResolver,
|
|
26
|
+
ReactRoot,
|
|
27
|
+
ReactSurface,
|
|
28
|
+
SpaceSettings,
|
|
29
|
+
SpacesReady,
|
|
30
|
+
SpaceState,
|
|
31
|
+
} from './capabilities';
|
|
32
|
+
import { SpaceEvents } from './events';
|
|
33
|
+
import { meta, SPACE_PLUGIN } from './meta';
|
|
90
34
|
import translations from './translations';
|
|
91
|
-
import {
|
|
92
|
-
CollectionType,
|
|
93
|
-
parseSchemaPlugin,
|
|
94
|
-
SpaceForm,
|
|
95
|
-
type PluginState,
|
|
96
|
-
type SpacePluginProvides,
|
|
97
|
-
type SpaceSettingsProps,
|
|
98
|
-
} from './types';
|
|
99
|
-
import {
|
|
100
|
-
COMPOSER_SPACE_LOCK,
|
|
101
|
-
SHARED,
|
|
102
|
-
SPACES,
|
|
103
|
-
SPACE_TYPE,
|
|
104
|
-
cloneObject,
|
|
105
|
-
constructObjectActions,
|
|
106
|
-
constructSpaceActions,
|
|
107
|
-
constructSpaceNode,
|
|
108
|
-
createObjectNode,
|
|
109
|
-
getNestedObjects,
|
|
110
|
-
memoizeQuery,
|
|
111
|
-
} from './util';
|
|
112
|
-
|
|
113
|
-
const ACTIVE_NODE_BROADCAST_INTERVAL = 30_000;
|
|
114
|
-
const WAIT_FOR_OBJECT_TIMEOUT = 1000;
|
|
115
|
-
const SPACE_MAX_OBJECTS = 500;
|
|
116
|
-
// https://stackoverflow.com/a/19016910
|
|
117
|
-
const DIRECTORY_TYPE = 'text/directory';
|
|
118
|
-
|
|
119
|
-
export const parseSpacePlugin = (plugin?: Plugin) =>
|
|
120
|
-
Array.isArray((plugin?.provides as any).space?.enabled) ? (plugin as Plugin<SpacePluginProvides>) : undefined;
|
|
35
|
+
import { CollectionAction, CollectionType } from './types';
|
|
121
36
|
|
|
122
37
|
export type SpacePluginOptions = {
|
|
123
38
|
/**
|
|
@@ -129,1447 +44,110 @@ export type SpacePluginOptions = {
|
|
|
129
44
|
* Query parameter for the invitation code.
|
|
130
45
|
*/
|
|
131
46
|
invitationParam?: string;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Fired when first run logic should be executed.
|
|
135
|
-
*
|
|
136
|
-
* This trigger is invoked once the HALO identity is created but must only be run in one instance of the application.
|
|
137
|
-
* As such it cannot depend directly on the HALO identity event.
|
|
138
|
-
*/
|
|
139
|
-
firstRun?: Trigger<void>;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Root collection structure is created on application first run if it does not yet exist.
|
|
143
|
-
* This callback is invoked immediately following the creation of the root collection structure.
|
|
144
|
-
*
|
|
145
|
-
* @param params.client DXOS Client
|
|
146
|
-
* @param params.dispatch Function to dispatch intents
|
|
147
|
-
*/
|
|
148
|
-
onFirstRun?: (params: { client: Client; dispatch: IntentDispatcher }) => Promise<void>;
|
|
149
47
|
};
|
|
150
48
|
|
|
151
49
|
export const SpacePlugin = ({
|
|
152
50
|
invitationUrl = window.location.origin,
|
|
153
51
|
invitationParam = 'spaceInvitationCode',
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}: SpacePluginOptions = {}): PluginDefinition<SpacePluginProvides> => {
|
|
157
|
-
const settings = new LocalStorageStore<SpaceSettingsProps>(SPACE_PLUGIN, {});
|
|
158
|
-
const state = new LocalStorageStore<PluginState>(SPACE_PLUGIN, {
|
|
159
|
-
awaiting: undefined,
|
|
160
|
-
spaceNames: {},
|
|
161
|
-
viewersByObject: {},
|
|
162
|
-
// TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
|
|
163
|
-
viewersByIdentity: new ComplexMap(PublicKey.hash),
|
|
164
|
-
sdkMigrationRunning: {},
|
|
165
|
-
navigableCollections: false,
|
|
166
|
-
enabledEdgeReplication: false,
|
|
167
|
-
});
|
|
168
|
-
const subscriptions = new EventSubscriptions();
|
|
169
|
-
const spaceSubscriptions = new EventSubscriptions();
|
|
170
|
-
const graphSubscriptions = new Map<string, UnsubscribeCallback>();
|
|
171
|
-
const schemas: AbstractTypedObject[] = [];
|
|
172
|
-
|
|
173
|
-
let clientPlugin: Plugin<ClientPluginProvides> | undefined;
|
|
174
|
-
let graphPlugin: Plugin<GraphProvides> | undefined;
|
|
175
|
-
let intentPlugin: Plugin<IntentPluginProvides> | undefined;
|
|
176
|
-
let layoutPlugin: Plugin<LayoutProvides> | undefined;
|
|
177
|
-
let navigationPlugin: Plugin<LocationProvides> | undefined;
|
|
178
|
-
let attentionPlugin: Plugin<AttentionPluginProvides> | undefined;
|
|
179
|
-
let metadataPlugin: Plugin<MetadataResolverProvides> | undefined;
|
|
180
|
-
|
|
181
|
-
const createSpaceInvitationUrl = (invitationCode: string) => {
|
|
52
|
+
}: SpacePluginOptions = {}) => {
|
|
53
|
+
const createInvitationUrl = (invitationCode: string) => {
|
|
182
54
|
const baseUrl = new URL(invitationUrl);
|
|
183
55
|
baseUrl.searchParams.set(invitationParam, invitationCode);
|
|
184
56
|
return baseUrl.toString();
|
|
185
57
|
};
|
|
186
58
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Await missing objects.
|
|
215
|
-
subscriptions.add(
|
|
216
|
-
scheduledEffect(
|
|
217
|
-
() => ({
|
|
218
|
-
layoutMode: layout.layoutMode,
|
|
219
|
-
soloPart: location.active.solo?.[0],
|
|
220
|
-
}),
|
|
221
|
-
({ layoutMode, soloPart }) => {
|
|
222
|
-
if (layoutMode !== 'solo' || !soloPart) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const node = graph.findNode(soloPart.id);
|
|
227
|
-
if (!node && soloPart.id.length === FQ_ID_LENGTH) {
|
|
228
|
-
const timeout = setTimeout(async () => {
|
|
229
|
-
const node = graph.findNode(soloPart.id);
|
|
230
|
-
if (!node) {
|
|
231
|
-
await dispatch({
|
|
232
|
-
plugin: SPACE_PLUGIN,
|
|
233
|
-
action: SpaceAction.WAIT_FOR_OBJECT,
|
|
234
|
-
data: { id: soloPart.id },
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}, WAIT_FOR_OBJECT_TIMEOUT);
|
|
238
|
-
|
|
239
|
-
return () => clearTimeout(timeout);
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
),
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
// Cache space names.
|
|
246
|
-
subscriptions.add(
|
|
247
|
-
client.spaces.subscribe(async (spaces) => {
|
|
248
|
-
// TODO(wittjosiah): Remove. This is a hack to be able to migrate the default space properties.
|
|
249
|
-
if (defaultSpace.state.get() === SpaceState.SPACE_REQUIRES_MIGRATION) {
|
|
250
|
-
await defaultSpace.internal.migrate();
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
spaces
|
|
254
|
-
.filter((space) => space.state.get() === SpaceState.SPACE_READY)
|
|
255
|
-
.forEach((space) => {
|
|
256
|
-
subscriptions.add(
|
|
257
|
-
scheduledEffect(
|
|
258
|
-
() => ({ name: space.properties.name }),
|
|
259
|
-
({ name }) => (state.values.spaceNames[space.id] = name),
|
|
260
|
-
),
|
|
261
|
-
);
|
|
262
|
-
});
|
|
263
|
-
}).unsubscribe,
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
// Broadcast active node to other peers in the space.
|
|
267
|
-
subscriptions.add(
|
|
268
|
-
scheduledEffect(
|
|
269
|
-
() => ({
|
|
270
|
-
open: openIds(location.active, layout.layoutMode === 'solo' ? ['solo'] : ['main']),
|
|
271
|
-
closed: [...location.closed],
|
|
272
|
-
}),
|
|
273
|
-
({ open, closed }) => {
|
|
274
|
-
const send = () => {
|
|
275
|
-
const spaces = client.spaces.get();
|
|
276
|
-
const identity = client.halo.identity.get();
|
|
277
|
-
if (identity && location.active) {
|
|
278
|
-
// Group parts by space for efficient messaging.
|
|
279
|
-
const idsBySpace = reduceGroupBy(open, (id) => {
|
|
280
|
-
try {
|
|
281
|
-
const [spaceId] = parseFullyQualifiedId(id);
|
|
282
|
-
return spaceId;
|
|
283
|
-
} catch {
|
|
284
|
-
return null;
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
const removedBySpace = reduceGroupBy(closed, (id) => {
|
|
289
|
-
try {
|
|
290
|
-
const [spaceId] = parseFullyQualifiedId(id);
|
|
291
|
-
return spaceId;
|
|
292
|
-
} catch {
|
|
293
|
-
return null;
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
// NOTE: Ensure all spaces are included so that we send the correct `removed` object arrays.
|
|
298
|
-
for (const space of spaces) {
|
|
299
|
-
if (!idsBySpace.has(space.id)) {
|
|
300
|
-
idsBySpace.set(space.id, []);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
for (const [spaceId, added] of idsBySpace) {
|
|
305
|
-
const removed = removedBySpace.get(spaceId) ?? [];
|
|
306
|
-
const space = spaces.find((space) => space.id === spaceId);
|
|
307
|
-
if (!space) {
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
void space
|
|
312
|
-
.postMessage('viewing', {
|
|
313
|
-
identityKey: identity.identityKey.toHex(),
|
|
314
|
-
attended: attention.attended ? [...attention.attended] : [],
|
|
315
|
-
added,
|
|
316
|
-
removed,
|
|
317
|
-
})
|
|
318
|
-
// TODO(burdon): This seems defensive; why would this fail? Backoff interval.
|
|
319
|
-
.catch((err) => {
|
|
320
|
-
log.warn('Failed to broadcast active node for presence.', { err: err.message });
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
send();
|
|
327
|
-
// Send at interval to allow peers to expire entries if they become disconnected.
|
|
328
|
-
const interval = setInterval(() => send(), ACTIVE_NODE_BROADCAST_INTERVAL);
|
|
329
|
-
return () => clearInterval(interval);
|
|
330
|
-
},
|
|
331
|
-
),
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
// Listen for active nodes from other peers in the space.
|
|
335
|
-
subscriptions.add(
|
|
336
|
-
client.spaces.subscribe((spaces) => {
|
|
337
|
-
spaceSubscriptions.clear();
|
|
338
|
-
spaces.forEach((space) => {
|
|
339
|
-
spaceSubscriptions.add(
|
|
340
|
-
space.listen('viewing', (message) => {
|
|
341
|
-
const { added, removed, attended } = message.payload;
|
|
342
|
-
|
|
343
|
-
const identityKey = PublicKey.safeFrom(message.payload.identityKey);
|
|
344
|
-
const currentIdentity = client.halo.identity.get();
|
|
345
|
-
if (
|
|
346
|
-
identityKey &&
|
|
347
|
-
!currentIdentity?.identityKey.equals(identityKey) &&
|
|
348
|
-
Array.isArray(added) &&
|
|
349
|
-
Array.isArray(removed)
|
|
350
|
-
) {
|
|
351
|
-
added.forEach((id) => {
|
|
352
|
-
if (typeof id === 'string') {
|
|
353
|
-
if (!(id in state.values.viewersByObject)) {
|
|
354
|
-
state.values.viewersByObject[id] = new ComplexMap(PublicKey.hash);
|
|
355
|
-
}
|
|
356
|
-
state.values.viewersByObject[id]!.set(identityKey, {
|
|
357
|
-
lastSeen: Date.now(),
|
|
358
|
-
currentlyAttended: new Set(attended).has(id),
|
|
359
|
-
});
|
|
360
|
-
if (!state.values.viewersByIdentity.has(identityKey)) {
|
|
361
|
-
state.values.viewersByIdentity.set(identityKey, new Set());
|
|
362
|
-
}
|
|
363
|
-
state.values.viewersByIdentity.get(identityKey)!.add(id);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
removed.forEach((id) => {
|
|
368
|
-
if (typeof id === 'string') {
|
|
369
|
-
state.values.viewersByObject[id]?.delete(identityKey);
|
|
370
|
-
state.values.viewersByIdentity.get(identityKey)?.delete(id);
|
|
371
|
-
// It’s okay for these to be empty sets/maps, reduces churn.
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
}),
|
|
376
|
-
);
|
|
377
|
-
});
|
|
378
|
-
}).unsubscribe,
|
|
379
|
-
);
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
const setEdgeReplicationDefault = async (client: Client) => {
|
|
383
|
-
try {
|
|
384
|
-
await Promise.all(
|
|
385
|
-
client.spaces.get().map((space) => space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED)),
|
|
386
|
-
);
|
|
387
|
-
state.values.enabledEdgeReplication = true;
|
|
388
|
-
} catch (err) {
|
|
389
|
-
log.catch(err);
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
return {
|
|
394
|
-
meta,
|
|
395
|
-
ready: async (plugins) => {
|
|
396
|
-
settings.prop({ key: 'showHidden', type: LocalStorageStore.bool({ allowUndefined: true }) });
|
|
397
|
-
state
|
|
398
|
-
.prop({ key: 'spaceNames', type: LocalStorageStore.json<Record<string, string>>() })
|
|
399
|
-
.prop({ key: 'enabledEdgeReplication', type: LocalStorageStore.bool() });
|
|
400
|
-
|
|
401
|
-
// TODO(wittjosiah): Hardcoded due to circular dependency.
|
|
402
|
-
// Should be based on a provides interface.
|
|
403
|
-
if (findPlugin(plugins, 'dxos.org/plugin/stack')) {
|
|
404
|
-
state.values.navigableCollections = true;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
408
|
-
layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
|
|
409
|
-
metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
|
|
410
|
-
navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
|
|
411
|
-
attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
|
|
412
|
-
clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
413
|
-
intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
|
|
414
|
-
if (!clientPlugin || !intentPlugin) {
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
const client = clientPlugin.provides.client;
|
|
419
|
-
const dispatch = intentPlugin.provides.intent.dispatch;
|
|
420
|
-
|
|
421
|
-
schemas.push(
|
|
422
|
-
...filterPlugins(plugins, parseSchemaPlugin)
|
|
423
|
-
.map((plugin) => plugin.provides.echo.schema)
|
|
424
|
-
.filter(nonNullable)
|
|
425
|
-
.reduce((acc, schema) => {
|
|
426
|
-
return [...acc, ...schema];
|
|
427
|
-
}),
|
|
428
|
-
);
|
|
429
|
-
client.addTypes(schemas);
|
|
430
|
-
filterPlugins(plugins, parseSchemaPlugin).forEach((plugin) => {
|
|
431
|
-
if (plugin.provides.echo.system) {
|
|
432
|
-
client.addTypes(plugin.provides.echo.system);
|
|
433
|
-
}
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
const handleFirstRun = async () => {
|
|
437
|
-
const defaultSpace = client.spaces.default;
|
|
438
|
-
|
|
439
|
-
// Create root collection structure.
|
|
440
|
-
defaultSpace.properties[CollectionType.typename] = create(CollectionType, { objects: [], views: {} });
|
|
441
|
-
if (Migrations.versionProperty) {
|
|
442
|
-
defaultSpace.properties[Migrations.versionProperty] = Migrations.targetVersion;
|
|
443
|
-
}
|
|
444
|
-
await onFirstRun?.({ client, dispatch });
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
subscriptions.add(
|
|
448
|
-
client.spaces.isReady.subscribe(async (ready) => {
|
|
449
|
-
if (ready) {
|
|
450
|
-
await clientPlugin?.provides.client.spaces.default.waitUntilReady();
|
|
451
|
-
if (firstRun) {
|
|
452
|
-
void firstRun?.wait().then(handleFirstRun);
|
|
453
|
-
} else {
|
|
454
|
-
await handleFirstRun();
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
await onSpaceReady();
|
|
458
|
-
await setEdgeReplicationDefault(client);
|
|
459
|
-
}
|
|
460
|
-
}).unsubscribe,
|
|
461
|
-
);
|
|
462
|
-
},
|
|
463
|
-
unload: async () => {
|
|
464
|
-
settings.close();
|
|
465
|
-
spaceSubscriptions.clear();
|
|
466
|
-
subscriptions.clear();
|
|
467
|
-
graphSubscriptions.forEach((cb) => cb());
|
|
468
|
-
graphSubscriptions.clear();
|
|
469
|
-
},
|
|
470
|
-
provides: {
|
|
471
|
-
space: state.values,
|
|
472
|
-
settings: settings.values,
|
|
473
|
-
translations: [...translations, osTranslations],
|
|
474
|
-
complementary: {
|
|
475
|
-
panels: [
|
|
476
|
-
{ id: 'settings', label: ['open settings panel label', { ns: SPACE_PLUGIN }], icon: 'ph--gear--regular' },
|
|
477
|
-
],
|
|
478
|
-
},
|
|
479
|
-
root: () => (state.values.awaiting ? <AwaitingObject id={state.values.awaiting} /> : null),
|
|
480
|
-
metadata: {
|
|
481
|
-
records: {
|
|
482
|
-
[CollectionType.typename]: {
|
|
483
|
-
createObject: CollectionAction.CREATE,
|
|
59
|
+
return definePlugin(meta, [
|
|
60
|
+
defineModule({
|
|
61
|
+
id: `${meta.id}/module/state`,
|
|
62
|
+
activatesOn: oneOf(Events.Startup, Events.SetupAppGraph),
|
|
63
|
+
activatesAfter: [SpaceEvents.StateReady],
|
|
64
|
+
activate: SpaceState,
|
|
65
|
+
}),
|
|
66
|
+
defineModule({
|
|
67
|
+
id: `${meta.id}/module/settings`,
|
|
68
|
+
activatesOn: Events.SetupSettings,
|
|
69
|
+
activate: SpaceSettings,
|
|
70
|
+
}),
|
|
71
|
+
defineModule({
|
|
72
|
+
id: `${meta.id}/module/translations`,
|
|
73
|
+
activatesOn: Events.SetupTranslations,
|
|
74
|
+
activate: () => contributes(Capabilities.Translations, [...translations, osTranslations]),
|
|
75
|
+
}),
|
|
76
|
+
defineModule({
|
|
77
|
+
id: `${meta.id}/module/metadata`,
|
|
78
|
+
activatesOn: oneOf(Events.Startup, Events.SetupAppGraph),
|
|
79
|
+
activate: () =>
|
|
80
|
+
contributes(Capabilities.Metadata, {
|
|
81
|
+
id: CollectionType.typename,
|
|
82
|
+
metadata: {
|
|
83
|
+
createObject: (props: { name?: string }) => createIntent(CollectionAction.Create, props),
|
|
484
84
|
placeholder: ['unnamed collection label', { ns: SPACE_PLUGIN }],
|
|
485
85
|
icon: 'ph--cards-three--regular',
|
|
486
86
|
// TODO(wittjosiah): Move out of metadata.
|
|
487
|
-
loadReferences: (collection: CollectionType) =>
|
|
488
|
-
|
|
489
|
-
...collection.objects,
|
|
490
|
-
...Object.values(collection.views),
|
|
491
|
-
]),
|
|
87
|
+
loadReferences: async (collection: CollectionType) =>
|
|
88
|
+
await RefArray.loadAll([...collection.objects, ...Object.values(collection.views)]),
|
|
492
89
|
},
|
|
493
|
-
},
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
<SmallPresenceLive
|
|
557
|
-
id={data.id as string}
|
|
558
|
-
viewers={state.values.viewersByObject[fullyQualifiedId(data.object)]}
|
|
559
|
-
/>
|
|
560
|
-
) : isSpace(data.object) ? (
|
|
561
|
-
<InlineSyncStatus space={data.object} />
|
|
562
|
-
) : (
|
|
563
|
-
// TODO(wittjosiah): Attention glyph for non-echo items should be handled elsewhere.
|
|
564
|
-
<SmallPresence id={data.id as string} count={0} />
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
case 'navbar-end': {
|
|
568
|
-
if (!isEchoObject(data.object) && !isSpace(data.object)) {
|
|
569
|
-
return null;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const space = isSpace(data.object) ? data.object : getSpace(data.object);
|
|
573
|
-
const object = isSpace(data.object)
|
|
574
|
-
? data.object.state.get() === SpaceState.SPACE_READY
|
|
575
|
-
? (space?.properties[CollectionType.typename] as CollectionType)
|
|
576
|
-
: undefined
|
|
577
|
-
: data.object;
|
|
578
|
-
|
|
579
|
-
return space && object
|
|
580
|
-
? {
|
|
581
|
-
node: (
|
|
582
|
-
<>
|
|
583
|
-
<SpacePresence object={object} />
|
|
584
|
-
{space.properties[COMPOSER_SPACE_LOCK] ? null : <ShareSpaceButton space={space} />}
|
|
585
|
-
</>
|
|
586
|
-
),
|
|
587
|
-
disposition: 'hoist',
|
|
588
|
-
}
|
|
589
|
-
: null;
|
|
590
|
-
}
|
|
591
|
-
case 'section':
|
|
592
|
-
return data.object instanceof CollectionType ? <CollectionSection collection={data.object} /> : null;
|
|
593
|
-
case 'settings':
|
|
594
|
-
return data.plugin === meta.id ? <SpacePluginSettings settings={settings.values} /> : null;
|
|
595
|
-
case 'menu-footer':
|
|
596
|
-
if (isEchoObject(data.object)) {
|
|
597
|
-
return <MenuFooter object={data.object} />;
|
|
598
|
-
} else {
|
|
599
|
-
return null;
|
|
600
|
-
}
|
|
601
|
-
case 'status': {
|
|
602
|
-
return <SyncStatus />;
|
|
603
|
-
}
|
|
604
|
-
default:
|
|
605
|
-
return null;
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
graph: {
|
|
610
|
-
builder: (plugins) => {
|
|
611
|
-
const clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
612
|
-
const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
|
|
613
|
-
const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
614
|
-
|
|
615
|
-
const client = clientPlugin?.provides.client;
|
|
616
|
-
const dispatch = intentPlugin?.provides.intent.dispatch;
|
|
617
|
-
const resolve = metadataPlugin?.provides.metadata.resolver;
|
|
618
|
-
const graph = graphPlugin?.provides.graph;
|
|
619
|
-
if (!client || !dispatch || !resolve || !graph) {
|
|
620
|
-
return [];
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
const spacesNode = {
|
|
624
|
-
id: SPACES,
|
|
625
|
-
type: SPACES,
|
|
626
|
-
cacheable: ['label', 'role'],
|
|
627
|
-
properties: {
|
|
628
|
-
label: ['spaces label', { ns: SPACE_PLUGIN }],
|
|
629
|
-
testId: 'spacePlugin.spaces',
|
|
630
|
-
role: 'branch',
|
|
631
|
-
disabled: true,
|
|
632
|
-
childrenPersistenceClass: 'echo',
|
|
633
|
-
onRearrangeChildren: async (nextOrder: Space[]) => {
|
|
634
|
-
// NOTE: This is needed to ensure order is updated by next animation frame.
|
|
635
|
-
// TODO(wittjosiah): Is there a better way to do this?
|
|
636
|
-
// If not, graph should be passed as an argument to the extension.
|
|
637
|
-
graph._sortEdges(
|
|
638
|
-
SPACES,
|
|
639
|
-
'outbound',
|
|
640
|
-
nextOrder.map(({ id }) => id),
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
const {
|
|
644
|
-
objects: [spacesOrder],
|
|
645
|
-
} = await client.spaces.default.db.query(Filter.schema(Expando, { key: SHARED })).run();
|
|
646
|
-
if (spacesOrder) {
|
|
647
|
-
spacesOrder.order = nextOrder.map(({ id }) => id);
|
|
648
|
-
} else {
|
|
649
|
-
log.warn('spaces order object not found');
|
|
650
|
-
}
|
|
651
|
-
},
|
|
652
|
-
},
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
return [
|
|
656
|
-
// Create spaces group node.
|
|
657
|
-
createExtension({
|
|
658
|
-
id: `${SPACE_PLUGIN}/root`,
|
|
659
|
-
filter: (node): node is Node<null> => node.id === 'root',
|
|
660
|
-
connector: () => [spacesNode],
|
|
661
|
-
resolver: ({ id }) => (id === SPACES ? spacesNode : undefined),
|
|
662
|
-
}),
|
|
663
|
-
|
|
664
|
-
// Create space nodes.
|
|
665
|
-
createExtension({
|
|
666
|
-
id: SPACES,
|
|
667
|
-
filter: (node): node is Node<null> => node.id === SPACES,
|
|
668
|
-
actions: () => [
|
|
669
|
-
{
|
|
670
|
-
id: SpaceAction.OPEN_CREATE_SPACE,
|
|
671
|
-
data: async () => {
|
|
672
|
-
await dispatch({
|
|
673
|
-
plugin: SPACE_PLUGIN,
|
|
674
|
-
action: SpaceAction.OPEN_CREATE_SPACE,
|
|
675
|
-
});
|
|
676
|
-
},
|
|
677
|
-
properties: {
|
|
678
|
-
label: ['create space label', { ns: SPACE_PLUGIN }],
|
|
679
|
-
icon: 'ph--plus--regular',
|
|
680
|
-
testId: 'spacePlugin.createSpace',
|
|
681
|
-
disposition: 'item',
|
|
682
|
-
className: 'border-t border-separator',
|
|
683
|
-
},
|
|
684
|
-
},
|
|
685
|
-
{
|
|
686
|
-
id: SpaceAction.JOIN,
|
|
687
|
-
data: async () => {
|
|
688
|
-
await dispatch({
|
|
689
|
-
plugin: SPACE_PLUGIN,
|
|
690
|
-
action: SpaceAction.JOIN,
|
|
691
|
-
});
|
|
692
|
-
},
|
|
693
|
-
properties: {
|
|
694
|
-
label: ['join space label', { ns: SPACE_PLUGIN }],
|
|
695
|
-
icon: 'ph--sign-in--regular',
|
|
696
|
-
testId: 'spacePlugin.joinSpace',
|
|
697
|
-
disposition: 'item',
|
|
698
|
-
},
|
|
699
|
-
},
|
|
700
|
-
],
|
|
701
|
-
connector: () => {
|
|
702
|
-
const spaces = toSignal(
|
|
703
|
-
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
704
|
-
() => client.spaces.get(),
|
|
705
|
-
);
|
|
706
|
-
|
|
707
|
-
const isReady = toSignal(
|
|
708
|
-
(onChange) => client.spaces.isReady.subscribe(() => onChange()).unsubscribe,
|
|
709
|
-
() => client.spaces.isReady.get(),
|
|
710
|
-
);
|
|
711
|
-
|
|
712
|
-
if (!spaces || !isReady) {
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
// TODO(wittjosiah): During client reset, accessing default space throws.
|
|
717
|
-
try {
|
|
718
|
-
const [spacesOrder] = memoizeQuery(client.spaces.default, Filter.schema(Expando, { key: SHARED }));
|
|
719
|
-
const order: string[] = spacesOrder?.order ?? [];
|
|
720
|
-
const orderMap = new Map(order.map((id, index) => [id, index]));
|
|
721
|
-
return [
|
|
722
|
-
...spaces
|
|
723
|
-
.filter((space) => orderMap.has(space.id))
|
|
724
|
-
.sort((a, b) => orderMap.get(a.id)! - orderMap.get(b.id)!),
|
|
725
|
-
...spaces.filter((space) => !orderMap.has(space.id)),
|
|
726
|
-
]
|
|
727
|
-
.filter((space) =>
|
|
728
|
-
settings.values.showHidden ? true : space.state.get() !== SpaceState.SPACE_INACTIVE,
|
|
729
|
-
)
|
|
730
|
-
.map((space) =>
|
|
731
|
-
constructSpaceNode({
|
|
732
|
-
space,
|
|
733
|
-
navigable: state.values.navigableCollections,
|
|
734
|
-
personal: space === client.spaces.default,
|
|
735
|
-
namesCache: state.values.spaceNames,
|
|
736
|
-
resolve,
|
|
737
|
-
}),
|
|
738
|
-
);
|
|
739
|
-
} catch {}
|
|
740
|
-
},
|
|
741
|
-
resolver: ({ id }) => {
|
|
742
|
-
if (id.length !== SPACE_ID_LENGTH) {
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
const spaces = toSignal(
|
|
747
|
-
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
748
|
-
() => client.spaces.get(),
|
|
749
|
-
);
|
|
750
|
-
|
|
751
|
-
const isReady = toSignal(
|
|
752
|
-
(onChange) => client.spaces.isReady.subscribe(() => onChange()).unsubscribe,
|
|
753
|
-
() => client.spaces.isReady.get(),
|
|
754
|
-
);
|
|
755
|
-
|
|
756
|
-
if (!spaces || !isReady) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
const space = spaces.find((space) => space.id === id);
|
|
761
|
-
if (!space) {
|
|
762
|
-
return;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
if (space.state.get() === SpaceState.SPACE_INACTIVE) {
|
|
766
|
-
return false;
|
|
767
|
-
} else {
|
|
768
|
-
return constructSpaceNode({
|
|
769
|
-
space,
|
|
770
|
-
navigable: state.values.navigableCollections,
|
|
771
|
-
personal: space === client.spaces.default,
|
|
772
|
-
namesCache: state.values.spaceNames,
|
|
773
|
-
resolve,
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
},
|
|
777
|
-
}),
|
|
778
|
-
|
|
779
|
-
// Create space actions.
|
|
780
|
-
createExtension({
|
|
781
|
-
id: `${SPACE_PLUGIN}/actions`,
|
|
782
|
-
filter: (node): node is Node<Space> => isSpace(node.data),
|
|
783
|
-
actions: ({ node }) => {
|
|
784
|
-
const space = node.data;
|
|
785
|
-
return constructSpaceActions({
|
|
786
|
-
space,
|
|
787
|
-
dispatch,
|
|
788
|
-
personal: space === client.spaces.default,
|
|
789
|
-
migrating: state.values.sdkMigrationRunning[space.id],
|
|
790
|
-
});
|
|
791
|
-
},
|
|
792
|
-
}),
|
|
793
|
-
|
|
794
|
-
// Create nodes for objects in the root collection of a space.
|
|
795
|
-
createExtension({
|
|
796
|
-
id: `${SPACE_PLUGIN}/root-collection`,
|
|
797
|
-
filter: (node): node is Node<Space> => isSpace(node.data),
|
|
798
|
-
connector: ({ node }) => {
|
|
799
|
-
const space = node.data;
|
|
800
|
-
const spaceState = toSignal(
|
|
801
|
-
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
802
|
-
() => space.state.get(),
|
|
803
|
-
space.id,
|
|
804
|
-
);
|
|
805
|
-
if (spaceState !== SpaceState.SPACE_READY) {
|
|
806
|
-
return;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
const collection = space.properties[CollectionType.typename] as CollectionType | undefined;
|
|
810
|
-
if (!collection) {
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
return collection.objects
|
|
815
|
-
.filter(nonNullable)
|
|
816
|
-
.map((object) =>
|
|
817
|
-
createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections }),
|
|
818
|
-
)
|
|
819
|
-
.filter(nonNullable);
|
|
820
|
-
},
|
|
821
|
-
}),
|
|
822
|
-
|
|
823
|
-
// Create nodes for objects in a collection or by its fully qualified id.
|
|
824
|
-
createExtension({
|
|
825
|
-
id: `${SPACE_PLUGIN}/objects`,
|
|
826
|
-
filter: (node): node is Node<CollectionType> => node.data instanceof CollectionType,
|
|
827
|
-
connector: ({ node }) => {
|
|
828
|
-
const collection = node.data;
|
|
829
|
-
const space = getSpace(collection);
|
|
830
|
-
if (!space) {
|
|
831
|
-
return;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
return collection.objects
|
|
835
|
-
.filter(nonNullable)
|
|
836
|
-
.map((object) =>
|
|
837
|
-
createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections }),
|
|
838
|
-
)
|
|
839
|
-
.filter(nonNullable);
|
|
840
|
-
},
|
|
841
|
-
resolver: ({ id }) => {
|
|
842
|
-
if (id.length !== FQ_ID_LENGTH) {
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
const [spaceId, objectId] = id.split(':');
|
|
847
|
-
if (spaceId.length !== SPACE_ID_LENGTH && objectId.length !== OBJECT_ID_LENGTH) {
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
const space = client.spaces.get().find((space) => space.id === spaceId);
|
|
852
|
-
if (!space) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
const spaceState = toSignal(
|
|
857
|
-
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
858
|
-
() => space.state.get(),
|
|
859
|
-
space.id,
|
|
860
|
-
);
|
|
861
|
-
if (spaceState !== SpaceState.SPACE_READY) {
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
const store = memoize(() => signal(space.db.getObjectById(objectId)), id);
|
|
866
|
-
memoize(() => {
|
|
867
|
-
if (!store.value) {
|
|
868
|
-
void space.db
|
|
869
|
-
.query({ id: objectId })
|
|
870
|
-
.first()
|
|
871
|
-
.then((o) => (store.value = o))
|
|
872
|
-
.catch((err) => log.catch(err, { objectId }));
|
|
873
|
-
}
|
|
874
|
-
}, id);
|
|
875
|
-
const object = store.value;
|
|
876
|
-
if (!object) {
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
if (isDeleted(object)) {
|
|
881
|
-
return false;
|
|
882
|
-
} else {
|
|
883
|
-
return createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections });
|
|
884
|
-
}
|
|
885
|
-
},
|
|
886
|
-
}),
|
|
887
|
-
|
|
888
|
-
// Create collection actions and action groups.
|
|
889
|
-
createExtension({
|
|
890
|
-
id: `${SPACE_PLUGIN}/object-actions`,
|
|
891
|
-
filter: (node): node is Node<ReactiveEchoObject<any>> => isEchoObject(node.data),
|
|
892
|
-
actions: ({ node }) => constructObjectActions({ node, dispatch }),
|
|
893
|
-
}),
|
|
894
|
-
|
|
895
|
-
// Create nodes for object settings.
|
|
896
|
-
createExtension({
|
|
897
|
-
id: `${SPACE_PLUGIN}/settings-for-subject`,
|
|
898
|
-
resolver: ({ id }) => {
|
|
899
|
-
// TODO(Zan): Find util (or make one).
|
|
900
|
-
if (!id.endsWith('~settings')) {
|
|
901
|
-
return;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
const type = 'orphan-settings-for-subject';
|
|
905
|
-
const icon = 'ph--gear--regular';
|
|
906
|
-
|
|
907
|
-
const [subjectId] = id.split('~');
|
|
908
|
-
const { spaceId, objectId } = parseId(subjectId);
|
|
909
|
-
const spaces = toSignal(
|
|
910
|
-
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
911
|
-
() => client.spaces.get(),
|
|
912
|
-
);
|
|
913
|
-
const space = spaces?.find(
|
|
914
|
-
(space) => space.id === spaceId && space.state.get() === SpaceState.SPACE_READY,
|
|
915
|
-
);
|
|
916
|
-
if (!objectId) {
|
|
917
|
-
const label = space
|
|
918
|
-
? space.properties.name || ['unnamed space label', { ns: SPACE_PLUGIN }]
|
|
919
|
-
: ['unnamed object settings label', { ns: SPACE_PLUGIN }];
|
|
920
|
-
|
|
921
|
-
// TODO(wittjosiah): Support comments for arbitrary subjects.
|
|
922
|
-
// This is to ensure that the comments panel is not stuck on an old object.
|
|
923
|
-
return {
|
|
924
|
-
id,
|
|
925
|
-
type,
|
|
926
|
-
data: null,
|
|
927
|
-
properties: {
|
|
928
|
-
icon,
|
|
929
|
-
label,
|
|
930
|
-
showResolvedThreads: false,
|
|
931
|
-
object: null,
|
|
932
|
-
space,
|
|
933
|
-
},
|
|
934
|
-
};
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
const [object] = memoizeQuery(space, { id: objectId });
|
|
938
|
-
if (!object || !subjectId) {
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
const meta = resolve(getTypename(object) ?? '');
|
|
943
|
-
const label = meta.label?.(object) ||
|
|
944
|
-
object.name ||
|
|
945
|
-
meta.placeholder || ['unnamed object settings label', { ns: SPACE_PLUGIN }];
|
|
946
|
-
|
|
947
|
-
return {
|
|
948
|
-
id,
|
|
949
|
-
type,
|
|
950
|
-
data: null,
|
|
951
|
-
properties: {
|
|
952
|
-
icon,
|
|
953
|
-
label,
|
|
954
|
-
object,
|
|
955
|
-
},
|
|
956
|
-
};
|
|
957
|
-
},
|
|
958
|
-
}),
|
|
959
|
-
];
|
|
960
|
-
},
|
|
961
|
-
serializer: (plugins) => {
|
|
962
|
-
const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
|
|
963
|
-
if (!dispatch) {
|
|
964
|
-
return [];
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
return [
|
|
968
|
-
{
|
|
969
|
-
inputType: SPACES,
|
|
970
|
-
outputType: DIRECTORY_TYPE,
|
|
971
|
-
serialize: (node) => ({
|
|
972
|
-
name: translations[0]['en-US'][SPACE_PLUGIN]['spaces label'],
|
|
973
|
-
data: translations[0]['en-US'][SPACE_PLUGIN]['spaces label'],
|
|
974
|
-
type: DIRECTORY_TYPE,
|
|
975
|
-
}),
|
|
976
|
-
deserialize: () => {
|
|
977
|
-
// No-op.
|
|
978
|
-
},
|
|
979
|
-
},
|
|
980
|
-
{
|
|
981
|
-
inputType: SPACE_TYPE,
|
|
982
|
-
outputType: DIRECTORY_TYPE,
|
|
983
|
-
serialize: (node) => ({
|
|
984
|
-
name: node.data.properties.name ?? translations[0]['en-US'][SPACE_PLUGIN]['unnamed space label'],
|
|
985
|
-
data: node.data.properties.name ?? translations[0]['en-US'][SPACE_PLUGIN]['unnamed space label'],
|
|
986
|
-
type: DIRECTORY_TYPE,
|
|
987
|
-
}),
|
|
988
|
-
deserialize: async (data) => {
|
|
989
|
-
const result = await dispatch({
|
|
990
|
-
plugin: SPACE_PLUGIN,
|
|
991
|
-
action: SpaceAction.CREATE,
|
|
992
|
-
data: { name: data.name },
|
|
993
|
-
});
|
|
994
|
-
return result?.data.space;
|
|
995
|
-
},
|
|
996
|
-
},
|
|
997
|
-
{
|
|
998
|
-
inputType: CollectionType.typename,
|
|
999
|
-
outputType: DIRECTORY_TYPE,
|
|
1000
|
-
serialize: (node) => ({
|
|
1001
|
-
name: node.data.name ?? translations[0]['en-US'][SPACE_PLUGIN]['unnamed collection label'],
|
|
1002
|
-
data: node.data.name ?? translations[0]['en-US'][SPACE_PLUGIN]['unnamed collection label'],
|
|
1003
|
-
type: DIRECTORY_TYPE,
|
|
1004
|
-
}),
|
|
1005
|
-
deserialize: async (data, ancestors) => {
|
|
1006
|
-
const space = ancestors.find(isSpace);
|
|
1007
|
-
const collection =
|
|
1008
|
-
ancestors.findLast((ancestor) => ancestor instanceof CollectionType) ??
|
|
1009
|
-
space?.properties[CollectionType.typename];
|
|
1010
|
-
if (!space || !collection) {
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
const result = await dispatch({
|
|
1015
|
-
plugin: SPACE_PLUGIN,
|
|
1016
|
-
action: SpaceAction.ADD_OBJECT,
|
|
1017
|
-
data: {
|
|
1018
|
-
target: collection,
|
|
1019
|
-
object: create(CollectionType, { name: data.name, objects: [], views: {} }),
|
|
1020
|
-
},
|
|
1021
|
-
});
|
|
1022
|
-
|
|
1023
|
-
return result?.data.object;
|
|
1024
|
-
},
|
|
1025
|
-
},
|
|
1026
|
-
];
|
|
1027
|
-
},
|
|
1028
|
-
},
|
|
1029
|
-
intent: {
|
|
1030
|
-
resolver: async (intent, plugins) => {
|
|
1031
|
-
const clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
1032
|
-
const client = clientPlugin?.provides.client;
|
|
1033
|
-
switch (intent.action) {
|
|
1034
|
-
case SpaceAction.WAIT_FOR_OBJECT: {
|
|
1035
|
-
state.values.awaiting = intent.data?.id;
|
|
1036
|
-
return { data: true };
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
case SpaceAction.OPEN_CREATE_SPACE: {
|
|
1040
|
-
return {
|
|
1041
|
-
data: true,
|
|
1042
|
-
intents: [
|
|
1043
|
-
[
|
|
1044
|
-
{
|
|
1045
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1046
|
-
data: {
|
|
1047
|
-
element: 'dialog',
|
|
1048
|
-
component: 'dxos.org/plugin/space/CreateSpaceDialog',
|
|
1049
|
-
dialogBlockAlign: 'start',
|
|
1050
|
-
subject: intent.data,
|
|
1051
|
-
},
|
|
1052
|
-
},
|
|
1053
|
-
],
|
|
1054
|
-
],
|
|
1055
|
-
};
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
case SpaceAction.CREATE: {
|
|
1059
|
-
if (!client || !S.is(SpaceForm)(intent.data)) {
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
const space = await client.spaces.create({ name: intent.data.name });
|
|
1064
|
-
if (intent.data.edgeReplication) {
|
|
1065
|
-
await space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED);
|
|
1066
|
-
}
|
|
1067
|
-
await space.waitUntilReady();
|
|
1068
|
-
const collection = create(CollectionType, { objects: [], views: {} });
|
|
1069
|
-
space.properties[CollectionType.typename] = collection;
|
|
1070
|
-
|
|
1071
|
-
if (Migrations.versionProperty) {
|
|
1072
|
-
space.properties[Migrations.versionProperty] = Migrations.targetVersion;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
return {
|
|
1076
|
-
data: {
|
|
1077
|
-
space,
|
|
1078
|
-
id: space.id,
|
|
1079
|
-
activeParts: { main: [space.id] },
|
|
1080
|
-
},
|
|
1081
|
-
intents: [
|
|
1082
|
-
[
|
|
1083
|
-
{
|
|
1084
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1085
|
-
data: {
|
|
1086
|
-
name: 'space.create',
|
|
1087
|
-
properties: {
|
|
1088
|
-
spaceId: space.id,
|
|
1089
|
-
},
|
|
1090
|
-
},
|
|
1091
|
-
},
|
|
1092
|
-
],
|
|
1093
|
-
],
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
case SpaceAction.JOIN: {
|
|
1098
|
-
return {
|
|
1099
|
-
data: true,
|
|
1100
|
-
intents: [
|
|
1101
|
-
[
|
|
1102
|
-
{
|
|
1103
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1104
|
-
data: {
|
|
1105
|
-
element: 'dialog',
|
|
1106
|
-
component: 'dxos.org/plugin/space/JoinDialog',
|
|
1107
|
-
dialogBlockAlign: 'start',
|
|
1108
|
-
subject: {
|
|
1109
|
-
initialInvitationCode: intent.data?.invitationCode,
|
|
1110
|
-
onDone: intent.data?.onDone,
|
|
1111
|
-
} satisfies Partial<JoinPanelProps>,
|
|
1112
|
-
},
|
|
1113
|
-
},
|
|
1114
|
-
],
|
|
1115
|
-
],
|
|
1116
|
-
};
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
case SpaceAction.SHARE: {
|
|
1120
|
-
const space = intent.data?.space;
|
|
1121
|
-
if (isSpace(space) && !space.properties[COMPOSER_SPACE_LOCK]) {
|
|
1122
|
-
const active = navigationPlugin?.provides.location.active;
|
|
1123
|
-
const mode = layoutPlugin?.provides.layout.layoutMode;
|
|
1124
|
-
const current = active ? firstIdInPart(active, mode === 'solo' ? 'solo' : 'main') : undefined;
|
|
1125
|
-
const target = current?.startsWith(space.id) ? current : undefined;
|
|
1126
|
-
|
|
1127
|
-
return {
|
|
1128
|
-
data: true,
|
|
1129
|
-
intents: [
|
|
1130
|
-
[
|
|
1131
|
-
{
|
|
1132
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1133
|
-
data: {
|
|
1134
|
-
element: 'dialog',
|
|
1135
|
-
component: 'dxos.org/plugin/space/SpaceSettingsDialog',
|
|
1136
|
-
dialogBlockAlign: 'start',
|
|
1137
|
-
subject: {
|
|
1138
|
-
space,
|
|
1139
|
-
target,
|
|
1140
|
-
initialTab: 'members',
|
|
1141
|
-
createInvitationUrl: createSpaceInvitationUrl,
|
|
1142
|
-
} satisfies Partial<SpaceSettingsDialogProps>,
|
|
1143
|
-
},
|
|
1144
|
-
},
|
|
1145
|
-
],
|
|
1146
|
-
[
|
|
1147
|
-
{
|
|
1148
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1149
|
-
data: {
|
|
1150
|
-
name: 'space.share',
|
|
1151
|
-
properties: {
|
|
1152
|
-
space: space.id,
|
|
1153
|
-
},
|
|
1154
|
-
},
|
|
1155
|
-
},
|
|
1156
|
-
],
|
|
1157
|
-
],
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
break;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
case SpaceAction.LOCK: {
|
|
1164
|
-
const space = intent.data?.space;
|
|
1165
|
-
if (isSpace(space)) {
|
|
1166
|
-
space.properties[COMPOSER_SPACE_LOCK] = true;
|
|
1167
|
-
return {
|
|
1168
|
-
data: true,
|
|
1169
|
-
intents: [
|
|
1170
|
-
[
|
|
1171
|
-
{
|
|
1172
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1173
|
-
data: {
|
|
1174
|
-
name: 'space.lock',
|
|
1175
|
-
properties: {
|
|
1176
|
-
spaceId: space.id,
|
|
1177
|
-
},
|
|
1178
|
-
},
|
|
1179
|
-
},
|
|
1180
|
-
],
|
|
1181
|
-
],
|
|
1182
|
-
};
|
|
1183
|
-
}
|
|
1184
|
-
break;
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
case SpaceAction.UNLOCK: {
|
|
1188
|
-
const space = intent.data?.space;
|
|
1189
|
-
if (isSpace(space)) {
|
|
1190
|
-
space.properties[COMPOSER_SPACE_LOCK] = false;
|
|
1191
|
-
return {
|
|
1192
|
-
data: true,
|
|
1193
|
-
intents: [
|
|
1194
|
-
[
|
|
1195
|
-
{
|
|
1196
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1197
|
-
data: {
|
|
1198
|
-
name: 'space.unlock',
|
|
1199
|
-
properties: {
|
|
1200
|
-
spaceId: space.id,
|
|
1201
|
-
},
|
|
1202
|
-
},
|
|
1203
|
-
},
|
|
1204
|
-
],
|
|
1205
|
-
],
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
break;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
case SpaceAction.RENAME: {
|
|
1212
|
-
const { caller, space } = intent.data ?? {};
|
|
1213
|
-
if (typeof caller === 'string' && isSpace(space)) {
|
|
1214
|
-
return {
|
|
1215
|
-
intents: [
|
|
1216
|
-
[
|
|
1217
|
-
{
|
|
1218
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1219
|
-
data: {
|
|
1220
|
-
element: 'popover',
|
|
1221
|
-
anchorId: `dxos.org/ui/${caller}/${space.id}`,
|
|
1222
|
-
component: 'dxos.org/plugin/space/RenameSpacePopover',
|
|
1223
|
-
subject: space,
|
|
1224
|
-
},
|
|
1225
|
-
},
|
|
1226
|
-
],
|
|
1227
|
-
],
|
|
1228
|
-
};
|
|
1229
|
-
}
|
|
1230
|
-
break;
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
case SpaceAction.OPEN_SETTINGS: {
|
|
1234
|
-
const space = intent.data?.space;
|
|
1235
|
-
if (isSpace(space)) {
|
|
1236
|
-
return {
|
|
1237
|
-
data: true,
|
|
1238
|
-
intents: [
|
|
1239
|
-
[
|
|
1240
|
-
{
|
|
1241
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1242
|
-
data: {
|
|
1243
|
-
element: 'dialog',
|
|
1244
|
-
component: 'dxos.org/plugin/space/SpaceSettingsDialog',
|
|
1245
|
-
dialogBlockAlign: 'start',
|
|
1246
|
-
subject: {
|
|
1247
|
-
space,
|
|
1248
|
-
initialTab: 'settings',
|
|
1249
|
-
createInvitationUrl: createSpaceInvitationUrl,
|
|
1250
|
-
} satisfies Partial<SpaceSettingsDialogProps>,
|
|
1251
|
-
},
|
|
1252
|
-
},
|
|
1253
|
-
],
|
|
1254
|
-
],
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
|
-
break;
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
case SpaceAction.OPEN: {
|
|
1261
|
-
const space = intent.data?.space;
|
|
1262
|
-
if (isSpace(space)) {
|
|
1263
|
-
await space.open();
|
|
1264
|
-
return { data: true };
|
|
1265
|
-
}
|
|
1266
|
-
break;
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
case SpaceAction.CLOSE: {
|
|
1270
|
-
const space = intent.data?.space;
|
|
1271
|
-
if (isSpace(space)) {
|
|
1272
|
-
await space.close();
|
|
1273
|
-
return { data: true };
|
|
1274
|
-
}
|
|
1275
|
-
break;
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
case SpaceAction.MIGRATE: {
|
|
1279
|
-
const space = intent.data?.space;
|
|
1280
|
-
if (isSpace(space)) {
|
|
1281
|
-
if (space.state.get() === SpaceState.SPACE_REQUIRES_MIGRATION) {
|
|
1282
|
-
state.values.sdkMigrationRunning[space.id] = true;
|
|
1283
|
-
await space.internal.migrate();
|
|
1284
|
-
state.values.sdkMigrationRunning[space.id] = false;
|
|
1285
|
-
}
|
|
1286
|
-
const result = await Migrations.migrate(space, intent.data?.version);
|
|
1287
|
-
return {
|
|
1288
|
-
data: result,
|
|
1289
|
-
intents: [
|
|
1290
|
-
[
|
|
1291
|
-
{
|
|
1292
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1293
|
-
data: {
|
|
1294
|
-
name: 'space.migrate',
|
|
1295
|
-
properties: {
|
|
1296
|
-
spaceId: space.id,
|
|
1297
|
-
version: intent.data?.version,
|
|
1298
|
-
},
|
|
1299
|
-
},
|
|
1300
|
-
},
|
|
1301
|
-
],
|
|
1302
|
-
],
|
|
1303
|
-
};
|
|
1304
|
-
}
|
|
1305
|
-
break;
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
case SpaceAction.OPEN_CREATE_OBJECT: {
|
|
1309
|
-
return {
|
|
1310
|
-
data: true,
|
|
1311
|
-
intents: [
|
|
1312
|
-
[
|
|
1313
|
-
{
|
|
1314
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1315
|
-
data: {
|
|
1316
|
-
element: 'dialog',
|
|
1317
|
-
component: 'dxos.org/plugin/space/CreateObjectDialog',
|
|
1318
|
-
dialogBlockAlign: 'start',
|
|
1319
|
-
subject: intent.data,
|
|
1320
|
-
},
|
|
1321
|
-
},
|
|
1322
|
-
],
|
|
1323
|
-
],
|
|
1324
|
-
};
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
case SpaceAction.ADD_OBJECT: {
|
|
1328
|
-
const object = intent.data?.object ?? intent.data?.result;
|
|
1329
|
-
if (!isReactiveObject(object)) {
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
const space = isSpace(intent.data?.target) ? intent.data?.target : getSpace(intent.data?.target);
|
|
1334
|
-
if (!space) {
|
|
1335
|
-
return;
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
if (space.db.coreDatabase.getAllObjectIds().length >= SPACE_MAX_OBJECTS) {
|
|
1339
|
-
return {
|
|
1340
|
-
data: false,
|
|
1341
|
-
intents: [
|
|
1342
|
-
[
|
|
1343
|
-
{
|
|
1344
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1345
|
-
data: {
|
|
1346
|
-
element: 'toast',
|
|
1347
|
-
subject: {
|
|
1348
|
-
id: `${SPACE_PLUGIN}/space-limit`,
|
|
1349
|
-
title: translations[0]['en-US'][SPACE_PLUGIN]['space limit label'],
|
|
1350
|
-
description: translations[0]['en-US'][SPACE_PLUGIN]['space limit description'],
|
|
1351
|
-
duration: 5_000,
|
|
1352
|
-
icon: 'ph--warning--regular',
|
|
1353
|
-
actionLabel: translations[0]['en-US'][SPACE_PLUGIN]['remove deleted objects label'],
|
|
1354
|
-
actionAlt: translations[0]['en-US'][SPACE_PLUGIN]['remove deleted objects alt'],
|
|
1355
|
-
// TODO(wittjosiah): Use OS namespace.
|
|
1356
|
-
closeLabel: translations[0]['en-US'][SPACE_PLUGIN]['space limit close label'],
|
|
1357
|
-
onAction: () => space.db.coreDatabase.unlinkDeletedObjects(),
|
|
1358
|
-
},
|
|
1359
|
-
},
|
|
1360
|
-
},
|
|
1361
|
-
],
|
|
1362
|
-
[
|
|
1363
|
-
{
|
|
1364
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1365
|
-
data: {
|
|
1366
|
-
name: 'space.limit',
|
|
1367
|
-
properties: {
|
|
1368
|
-
spaceId: space.id,
|
|
1369
|
-
},
|
|
1370
|
-
},
|
|
1371
|
-
},
|
|
1372
|
-
],
|
|
1373
|
-
],
|
|
1374
|
-
};
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
if (intent.data?.target instanceof CollectionType) {
|
|
1378
|
-
intent.data?.target.objects.push(object as HasId);
|
|
1379
|
-
} else if (isSpace(intent.data?.target)) {
|
|
1380
|
-
const collection = space.properties[CollectionType.typename];
|
|
1381
|
-
if (collection instanceof CollectionType) {
|
|
1382
|
-
collection.objects.push(object as HasId);
|
|
1383
|
-
} else {
|
|
1384
|
-
// TODO(wittjosiah): Can't add non-echo objects by including in a collection because of types.
|
|
1385
|
-
const collection = create(CollectionType, { objects: [object as HasId], views: {} });
|
|
1386
|
-
space.properties[CollectionType.typename] = collection;
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
|
-
return {
|
|
1391
|
-
data: { id: fullyQualifiedId(object), object, activeParts: { main: [fullyQualifiedId(object)] } },
|
|
1392
|
-
intents: [
|
|
1393
|
-
[
|
|
1394
|
-
{
|
|
1395
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
1396
|
-
data: {
|
|
1397
|
-
name: 'space.object.add',
|
|
1398
|
-
properties: {
|
|
1399
|
-
spaceId: space.id,
|
|
1400
|
-
objectId: object.id,
|
|
1401
|
-
typename: getTypename(object),
|
|
1402
|
-
},
|
|
1403
|
-
},
|
|
1404
|
-
},
|
|
1405
|
-
],
|
|
1406
|
-
],
|
|
1407
|
-
};
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
case SpaceAction.REMOVE_OBJECTS: {
|
|
1411
|
-
const objects = intent.data?.objects ?? intent.data?.result;
|
|
1412
|
-
invariant(Array.isArray(objects));
|
|
1413
|
-
|
|
1414
|
-
// All objects must be a member of the same space.
|
|
1415
|
-
const space = getSpace(objects[0]);
|
|
1416
|
-
if (!space || !objects.every((obj) => isEchoObject(obj) && getSpace(obj) === space)) {
|
|
1417
|
-
return;
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
|
|
1421
|
-
const activeParts = navigationPlugin?.provides.location.active;
|
|
1422
|
-
const openObjectIds = new Set<string>(openIds(activeParts ?? {}));
|
|
1423
|
-
|
|
1424
|
-
if (!intent.undo && resolve) {
|
|
1425
|
-
const parentCollection = intent.data?.collection ?? space.properties[CollectionType.typename];
|
|
1426
|
-
const nestedObjectsList = await Promise.all(objects.map((obj) => getNestedObjects(obj, resolve)));
|
|
1427
|
-
|
|
1428
|
-
const deletionData = {
|
|
1429
|
-
objects,
|
|
1430
|
-
parentCollection,
|
|
1431
|
-
indices: objects.map((obj) =>
|
|
1432
|
-
parentCollection instanceof CollectionType ? parentCollection.objects.indexOf(obj as Expando) : -1,
|
|
1433
|
-
),
|
|
1434
|
-
nestedObjectsList,
|
|
1435
|
-
wasActive: objects
|
|
1436
|
-
.flatMap((obj, i) => [obj, ...nestedObjectsList[i]])
|
|
1437
|
-
.map((obj) => fullyQualifiedId(obj))
|
|
1438
|
-
.filter((id) => openObjectIds.has(id)),
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
if (deletionData.wasActive.length > 0) {
|
|
1442
|
-
await intentPlugin?.provides.intent.dispatch({
|
|
1443
|
-
action: NavigationAction.CLOSE,
|
|
1444
|
-
data: {
|
|
1445
|
-
activeParts: {
|
|
1446
|
-
main: deletionData.wasActive,
|
|
1447
|
-
sidebar: deletionData.wasActive,
|
|
1448
|
-
},
|
|
1449
|
-
},
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
if (deletionData.parentCollection instanceof CollectionType) {
|
|
1454
|
-
[...deletionData.indices]
|
|
1455
|
-
.sort((a, b) => b - a)
|
|
1456
|
-
.forEach((index: number) => {
|
|
1457
|
-
if (index !== -1) {
|
|
1458
|
-
deletionData.parentCollection.objects.splice(index, 1);
|
|
1459
|
-
}
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
deletionData.nestedObjectsList.flat().forEach((obj) => {
|
|
1464
|
-
space.db.remove(obj);
|
|
1465
|
-
});
|
|
1466
|
-
objects.forEach((obj) => space.db.remove(obj));
|
|
1467
|
-
|
|
1468
|
-
const undoMessageKey = objects.some((obj) => obj instanceof CollectionType)
|
|
1469
|
-
? 'collection deleted label'
|
|
1470
|
-
: objects.length > 1
|
|
1471
|
-
? 'objects deleted label'
|
|
1472
|
-
: 'object deleted label';
|
|
1473
|
-
|
|
1474
|
-
return {
|
|
1475
|
-
data: true,
|
|
1476
|
-
undoable: {
|
|
1477
|
-
// TODO(ZaymonFC): Pluralize if more than one object.
|
|
1478
|
-
message: translations[0]['en-US'][SPACE_PLUGIN][undoMessageKey],
|
|
1479
|
-
data: deletionData,
|
|
1480
|
-
},
|
|
1481
|
-
};
|
|
1482
|
-
} else {
|
|
1483
|
-
const undoData = intent.data;
|
|
1484
|
-
if (
|
|
1485
|
-
undoData?.objects?.length &&
|
|
1486
|
-
undoData.objects.every(isEchoObject) &&
|
|
1487
|
-
undoData.parentCollection instanceof CollectionType
|
|
1488
|
-
) {
|
|
1489
|
-
// Restore the object to the space.
|
|
1490
|
-
const restoredObjects = undoData.objects.map((obj: Expando) => space.db.add(obj));
|
|
1491
|
-
|
|
1492
|
-
// Restore nested objects to the space.
|
|
1493
|
-
undoData.nestedObjectsList.flat().forEach((obj: Expando) => {
|
|
1494
|
-
space.db.add(obj);
|
|
1495
|
-
});
|
|
1496
|
-
|
|
1497
|
-
undoData.indices.forEach((index: number, i: number) => {
|
|
1498
|
-
if (index !== -1) {
|
|
1499
|
-
undoData.parentCollection.objects.splice(index, 0, restoredObjects[i] as Expando);
|
|
1500
|
-
}
|
|
1501
|
-
});
|
|
1502
|
-
|
|
1503
|
-
if (undoData.wasActive.length > 0) {
|
|
1504
|
-
await intentPlugin?.provides.intent.dispatch({
|
|
1505
|
-
action: NavigationAction.OPEN,
|
|
1506
|
-
data: { activeParts: { main: undoData.wasActive } },
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
return { data: true };
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
return { data: false };
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
case SpaceAction.RENAME_OBJECT: {
|
|
1518
|
-
const object = intent.data?.object ?? intent.data?.result;
|
|
1519
|
-
const caller = intent.data?.caller;
|
|
1520
|
-
if (isReactiveObject(object) && caller) {
|
|
1521
|
-
return {
|
|
1522
|
-
intents: [
|
|
1523
|
-
[
|
|
1524
|
-
{
|
|
1525
|
-
action: LayoutAction.SET_LAYOUT,
|
|
1526
|
-
data: {
|
|
1527
|
-
element: 'popover',
|
|
1528
|
-
anchorId: `dxos.org/ui/${caller}/${fullyQualifiedId(object)}`,
|
|
1529
|
-
component: 'dxos.org/plugin/space/RenameObjectPopover',
|
|
1530
|
-
subject: object,
|
|
1531
|
-
},
|
|
1532
|
-
},
|
|
1533
|
-
],
|
|
1534
|
-
],
|
|
1535
|
-
};
|
|
1536
|
-
}
|
|
1537
|
-
break;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
case SpaceAction.DUPLICATE_OBJECT: {
|
|
1541
|
-
const originalObject = intent.data?.object ?? intent.data?.result;
|
|
1542
|
-
const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
|
|
1543
|
-
const space = isSpace(intent.data?.target) ? intent.data?.target : getSpace(intent.data?.target);
|
|
1544
|
-
if (!isEchoObject(originalObject) || !resolve || !space) {
|
|
1545
|
-
return;
|
|
1546
|
-
}
|
|
1547
|
-
|
|
1548
|
-
const newObject = await cloneObject(originalObject, resolve, space);
|
|
1549
|
-
return {
|
|
1550
|
-
intents: [
|
|
1551
|
-
[{ action: SpaceAction.ADD_OBJECT, data: { object: newObject, target: intent.data?.target } }],
|
|
1552
|
-
],
|
|
1553
|
-
};
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
case SpaceAction.TOGGLE_HIDDEN: {
|
|
1557
|
-
settings.values.showHidden = intent.data?.state ?? !settings.values.showHidden;
|
|
1558
|
-
return { data: true };
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
case CollectionAction.CREATE: {
|
|
1562
|
-
const collection = create(CollectionType, {
|
|
1563
|
-
name: intent.data?.name,
|
|
1564
|
-
objects: [],
|
|
1565
|
-
views: {},
|
|
1566
|
-
});
|
|
1567
|
-
|
|
1568
|
-
return { data: collection };
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
},
|
|
1572
|
-
},
|
|
1573
|
-
},
|
|
1574
|
-
};
|
|
90
|
+
}),
|
|
91
|
+
}),
|
|
92
|
+
defineModule({
|
|
93
|
+
id: `${meta.id}/module/complementary-panel`,
|
|
94
|
+
activatesOn: Events.Startup,
|
|
95
|
+
activate: () =>
|
|
96
|
+
contributes(DeckCapabilities.ComplementaryPanel, {
|
|
97
|
+
id: 'settings',
|
|
98
|
+
label: ['settings panel label', { ns: SPACE_PLUGIN }],
|
|
99
|
+
icon: 'ph--gear--regular',
|
|
100
|
+
}),
|
|
101
|
+
}),
|
|
102
|
+
defineModule({
|
|
103
|
+
id: `${meta.id}/module/schema`,
|
|
104
|
+
activatesOn: ClientEvents.SetupClient,
|
|
105
|
+
activate: () => contributes(ClientCapabilities.Schema, [CollectionType]),
|
|
106
|
+
}),
|
|
107
|
+
defineModule({
|
|
108
|
+
id: `${meta.id}/module/react-root`,
|
|
109
|
+
activatesOn: Events.Startup,
|
|
110
|
+
activate: ReactRoot,
|
|
111
|
+
}),
|
|
112
|
+
defineModule({
|
|
113
|
+
id: `${meta.id}/module/react-surface`,
|
|
114
|
+
activatesOn: Events.Startup,
|
|
115
|
+
activate: () => ReactSurface({ createInvitationUrl }),
|
|
116
|
+
}),
|
|
117
|
+
defineModule({
|
|
118
|
+
id: `${meta.id}/module/intent-resolver`,
|
|
119
|
+
activatesOn: Events.SetupIntents,
|
|
120
|
+
activate: (context) => IntentResolver({ createInvitationUrl, context }),
|
|
121
|
+
}),
|
|
122
|
+
defineModule({
|
|
123
|
+
id: `${meta.id}/module/app-graph-builder`,
|
|
124
|
+
activatesOn: Events.SetupAppGraph,
|
|
125
|
+
activate: AppGraphBuilder,
|
|
126
|
+
}),
|
|
127
|
+
// TODO(wittjosiah): This could probably be deferred.
|
|
128
|
+
defineModule({
|
|
129
|
+
id: `${meta.id}/module/app-graph-serializer`,
|
|
130
|
+
activatesOn: Events.Startup,
|
|
131
|
+
activate: AppGraphSerializer,
|
|
132
|
+
}),
|
|
133
|
+
defineModule({
|
|
134
|
+
id: `${meta.id}/module/identity-created`,
|
|
135
|
+
activatesOn: ClientEvents.IdentityCreated,
|
|
136
|
+
activatesAfter: [SpaceEvents.DefaultSpaceReady],
|
|
137
|
+
activate: IdentityCreated,
|
|
138
|
+
}),
|
|
139
|
+
defineModule({
|
|
140
|
+
id: `${meta.id}/module/spaces-ready`,
|
|
141
|
+
activatesOn: allOf(
|
|
142
|
+
Events.DispatcherReady,
|
|
143
|
+
Events.LayoutReady,
|
|
144
|
+
Events.LocationReady,
|
|
145
|
+
Events.AppGraphReady,
|
|
146
|
+
AttentionEvents.AttentionReady,
|
|
147
|
+
SpaceEvents.StateReady,
|
|
148
|
+
ClientEvents.SpacesReady,
|
|
149
|
+
),
|
|
150
|
+
activate: SpacesReady,
|
|
151
|
+
}),
|
|
152
|
+
]);
|
|
1575
153
|
};
|