@dxos/client-services 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/{chunk-6C7MTZLC.mjs → chunk-HPR4MJ4W.mjs} +2916 -3802
- package/dist/lib/browser/chunk-HPR4MJ4W.mjs.map +7 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
- package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
- package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +576 -139
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/browser.mjs +86 -0
- package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/node.mjs +48 -0
- package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +59 -55
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YOHACH7G.mjs → chunk-JW6QHPRJ.mjs} +2859 -3614
- package/dist/lib/node-esm/chunk-JW6QHPRJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +576 -139
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs +86 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +59 -55
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts +7 -3
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts +2 -2
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts +3 -3
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +10 -10
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +14 -9
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +7 -11
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +10 -13
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +7 -6
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +7 -4
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +5 -5
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +6 -5
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/index.d.ts +1 -1
- package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +5 -4
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +75 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/index.d.ts +1 -0
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +22 -19
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +20 -13
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
- package/dist/types/src/packlets/services/sqlite-storage.d.ts +27 -0
- package/dist/types/src/packlets/services/sqlite-storage.d.ts.map +1 -0
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
- package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/index.d.ts +4 -1
- package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +49 -22
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +38 -13
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +4 -3
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/index.d.ts +1 -0
- package/dist/types/src/packlets/storage/index.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts +24 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts.map +1 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts +2 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts.map +1 -0
- package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +20 -22
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +71 -57
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +10 -7
- package/src/packlets/agents/edge-agent-service.ts +15 -3
- package/src/packlets/devices/devices-service.test.ts +0 -1
- package/src/packlets/devices/devices-service.ts +1 -1
- package/src/packlets/devtools/devtools.ts +28 -7
- package/src/packlets/devtools/feeds.ts +1 -1
- package/src/packlets/devtools/keys.ts +2 -2
- package/src/packlets/devtools/spaces.ts +1 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/diagnostics/index.ts +1 -1
- package/src/packlets/identity/authenticator.ts +3 -3
- package/src/packlets/identity/contacts-service.ts +1 -2
- package/src/packlets/identity/identity-manager.test.ts +6 -6
- package/src/packlets/identity/identity-manager.ts +29 -28
- package/src/packlets/identity/identity-recovery-manager.ts +31 -22
- package/src/packlets/identity/identity-service.test.ts +6 -27
- package/src/packlets/identity/identity-service.ts +17 -83
- package/src/packlets/identity/identity.test.ts +7 -7
- package/src/packlets/identity/identity.ts +12 -35
- package/src/packlets/invitations/device-invitation-protocol.ts +10 -9
- package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
- package/src/packlets/invitations/invitation-guest-extenstion.ts +6 -4
- package/src/packlets/invitations/invitation-host-extension.ts +13 -14
- package/src/packlets/invitations/invitation-protocol.ts +7 -4
- package/src/packlets/invitations/invitation-state.ts +1 -15
- package/src/packlets/invitations/invitations-handler.test.ts +4 -5
- package/src/packlets/invitations/invitations-handler.ts +74 -22
- package/src/packlets/invitations/invitations-manager.ts +42 -17
- package/src/packlets/invitations/invitations-service.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
- package/src/packlets/invitations/space-invitation-protocol.ts +13 -18
- package/src/packlets/locks/index.ts +1 -1
- package/src/packlets/logging/logging-service.ts +20 -16
- package/src/packlets/network/network-service.test.ts +0 -1
- package/src/packlets/network/network-service.ts +10 -8
- package/src/packlets/services/client-rpc-server.ts +19 -16
- package/src/packlets/services/feed-syncer.test.ts +376 -0
- package/src/packlets/services/feed-syncer.ts +536 -0
- package/src/packlets/services/index.ts +1 -0
- package/src/packlets/services/platform.ts +7 -1
- package/src/packlets/services/service-context.test.ts +3 -2
- package/src/packlets/services/service-context.ts +218 -80
- package/src/packlets/services/service-host.test.ts +8 -10
- package/src/packlets/services/service-host.ts +104 -65
- package/src/packlets/services/service-registry.test.ts +0 -1
- package/src/packlets/services/sqlite-storage.ts +390 -0
- package/src/packlets/space-export/archive-format.ts +42 -0
- package/src/packlets/space-export/index.ts +4 -1
- package/src/packlets/space-export/serialized-space-reader.ts +129 -0
- package/src/packlets/space-export/serialized-space-writer.ts +260 -0
- package/src/packlets/space-export/space-archive-reader.ts +65 -4
- package/src/packlets/space-export/space-archive-writer.ts +43 -5
- package/src/packlets/space-export/space-archive.test.ts +482 -0
- package/src/packlets/spaces/data-space-manager.test.ts +169 -14
- package/src/packlets/spaces/data-space-manager.ts +209 -128
- package/src/packlets/spaces/data-space.ts +89 -43
- package/src/packlets/spaces/edge-feed-replicator.test.ts +3 -3
- package/src/packlets/spaces/edge-feed-replicator.ts +12 -10
- package/src/packlets/spaces/epoch-migrations.ts +7 -6
- package/src/packlets/spaces/genesis.ts +9 -4
- package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.ts +10 -9
- package/src/packlets/spaces/spaces-service.test.ts +18 -11
- package/src/packlets/spaces/spaces-service.ts +131 -25
- package/src/packlets/storage/index.ts +1 -0
- package/src/packlets/storage/profile-archive-sqlite.test.ts +79 -0
- package/src/packlets/storage/profile-archive-sqlite.ts +100 -0
- package/src/packlets/storage/profile-archive.ts +3 -0
- package/src/packlets/storage/storage.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +10 -6
- package/src/packlets/testing/test-builder.ts +59 -40
- package/src/packlets/worker/worker-runtime.ts +173 -17
- package/src/packlets/worker/worker-session.ts +12 -18
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-6C7MTZLC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YOHACH7G.mjs.map +0 -7
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
- package/src/packlets/identity/default-space-state-machine.ts +0 -44
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Doc } from '@automerge/automerge';
|
|
6
|
-
import { type AutomergeUrl, type
|
|
6
|
+
import { type AutomergeUrl, type DocumentId, interpretAsDocumentId } from '@automerge/automerge-repo';
|
|
7
7
|
|
|
8
8
|
import { Event, synchronized, trackLeaks } from '@dxos/async';
|
|
9
|
-
import {
|
|
9
|
+
import { SpaceProperties } from '@dxos/client-protocol';
|
|
10
10
|
import { Context, LifecycleState, Resource, cancelWithContext } from '@dxos/context';
|
|
11
11
|
import {
|
|
12
12
|
type CredentialSigner,
|
|
@@ -15,61 +15,55 @@ import {
|
|
|
15
15
|
createAdmissionCredentials,
|
|
16
16
|
getCredentialAssertion,
|
|
17
17
|
} from '@dxos/credentials';
|
|
18
|
+
import { Type } from '@dxos/echo';
|
|
18
19
|
import {
|
|
19
20
|
AuthStatus,
|
|
20
21
|
CredentialServerExtension,
|
|
21
22
|
DatabaseRoot,
|
|
22
|
-
type EchoEdgeReplicator,
|
|
23
23
|
type EchoHost,
|
|
24
|
-
|
|
24
|
+
type EdgeAutomergeReplicator,
|
|
25
25
|
type MeshEchoReplicator,
|
|
26
|
-
type
|
|
26
|
+
type IMetadataStore,
|
|
27
27
|
type Space,
|
|
28
28
|
type SpaceManager,
|
|
29
29
|
type SpaceProtocol,
|
|
30
30
|
type SpaceProtocolSession,
|
|
31
31
|
findInlineObjectOfType,
|
|
32
|
-
} from '@dxos/echo-
|
|
33
|
-
import {
|
|
34
|
-
type DatabaseDirectory,
|
|
35
|
-
type ObjectStructure,
|
|
36
|
-
SpaceDocVersion,
|
|
37
|
-
createIdFromSpaceKey,
|
|
38
|
-
encodeReference,
|
|
39
|
-
} from '@dxos/echo-protocol';
|
|
40
|
-
import { ObjectId, getTypeReference } from '@dxos/echo-schema';
|
|
32
|
+
} from '@dxos/echo-host';
|
|
33
|
+
import { type DatabaseDirectory, createIdFromSpaceKey } from '@dxos/echo-protocol';
|
|
41
34
|
import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
|
|
42
35
|
import { type FeedStore, writeMessages } from '@dxos/feed-store';
|
|
43
36
|
import { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';
|
|
44
|
-
import { type
|
|
37
|
+
import { type KeyringApi } from '@dxos/keyring';
|
|
45
38
|
import { PublicKey, type SpaceId } from '@dxos/keys';
|
|
46
39
|
import { log } from '@dxos/log';
|
|
47
|
-
import { AlreadyJoinedError
|
|
40
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
48
41
|
import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
49
42
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
50
43
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
51
44
|
import { EdgeReplicationSetting, type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
52
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
type Credential,
|
|
47
|
+
MembershipPolicy,
|
|
48
|
+
type ProfileDocument,
|
|
49
|
+
SpaceMember,
|
|
50
|
+
} from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
53
51
|
import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
54
52
|
import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
|
|
55
53
|
import { type Teleport } from '@dxos/teleport';
|
|
56
54
|
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
57
55
|
import { type Timeframe } from '@dxos/timeframe';
|
|
58
56
|
import { trace } from '@dxos/tracing';
|
|
59
|
-
import { ComplexMap, deferFunction, forEachAsync
|
|
57
|
+
import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
|
|
60
58
|
|
|
61
59
|
import { createAuthProvider } from '../identity';
|
|
62
60
|
import { type InvitationsManager } from '../invitations';
|
|
63
|
-
|
|
64
61
|
import { DataSpace } from './data-space';
|
|
65
62
|
import { spaceGenesis } from './genesis';
|
|
66
63
|
|
|
67
64
|
const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
|
|
68
65
|
const PRESENCE_OFFLINE_TIMEOUT = 20_000;
|
|
69
66
|
|
|
70
|
-
// Space properties key for default metadata.
|
|
71
|
-
const DEFAULT_SPACE_KEY = '__DEFAULT__';
|
|
72
|
-
|
|
73
67
|
export interface SigningContext {
|
|
74
68
|
identityKey: PublicKey;
|
|
75
69
|
deviceKey: PublicKey;
|
|
@@ -94,6 +88,9 @@ export type AcceptSpaceOptions = {
|
|
|
94
88
|
* We will try to catch up to this timeframe before initializing the database.
|
|
95
89
|
*/
|
|
96
90
|
dataTimeframe?: Timeframe;
|
|
91
|
+
|
|
92
|
+
/** Tags assigned to the space member. */
|
|
93
|
+
tags?: string[];
|
|
97
94
|
};
|
|
98
95
|
|
|
99
96
|
export type AdmitMemberOptions = {
|
|
@@ -102,12 +99,13 @@ export type AdmitMemberOptions = {
|
|
|
102
99
|
role: SpaceMember.Role;
|
|
103
100
|
profile?: ProfileDocument;
|
|
104
101
|
delegationCredentialId?: PublicKey;
|
|
102
|
+
tags?: string[];
|
|
105
103
|
};
|
|
106
104
|
|
|
107
|
-
export type
|
|
105
|
+
export type DataSpaceManagerProps = {
|
|
108
106
|
spaceManager: SpaceManager;
|
|
109
|
-
metadataStore:
|
|
110
|
-
keyring:
|
|
107
|
+
metadataStore: IMetadataStore;
|
|
108
|
+
keyring: KeyringApi;
|
|
111
109
|
signingContext: SigningContext;
|
|
112
110
|
feedStore: FeedStore<FeedMessage>;
|
|
113
111
|
echoHost: EchoHost;
|
|
@@ -115,34 +113,40 @@ export type DataSpaceManagerParams = {
|
|
|
115
113
|
edgeConnection?: EdgeConnection;
|
|
116
114
|
edgeHttpClient?: EdgeHttpClient;
|
|
117
115
|
meshReplicator?: MeshEchoReplicator;
|
|
118
|
-
echoEdgeReplicator?:
|
|
119
|
-
|
|
116
|
+
echoEdgeReplicator?: EdgeAutomergeReplicator;
|
|
117
|
+
runtimeProps?: DataSpaceManagerRuntimeProps;
|
|
120
118
|
edgeFeatures?: Runtime.Client.EdgeFeatures;
|
|
121
119
|
};
|
|
122
120
|
|
|
123
|
-
export type
|
|
121
|
+
export type DataSpaceManagerRuntimeProps = {
|
|
124
122
|
spaceMemberPresenceAnnounceInterval?: number;
|
|
125
123
|
spaceMemberPresenceOfflineTimeout?: number;
|
|
126
124
|
activeEdgeNotarizationPollingInterval?: number;
|
|
127
125
|
disableP2pReplication?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* If true, spaces that were previously SPACE_ACTIVE will be automatically activated on startup.
|
|
128
|
+
* This is used in dedicated worker mode to restore space state after leader changeover.
|
|
129
|
+
*/
|
|
130
|
+
autoActivateSpaces?: boolean;
|
|
128
131
|
};
|
|
129
132
|
|
|
130
133
|
export type CreateSpaceOptions = {
|
|
131
134
|
rootUrl?: AutomergeUrl;
|
|
132
135
|
documents?: Record<DocumentId, Uint8Array>;
|
|
136
|
+
tags?: string[];
|
|
137
|
+
membershipPolicy?: MembershipPolicy;
|
|
133
138
|
};
|
|
134
139
|
|
|
135
140
|
@trackLeaks('open', 'close')
|
|
141
|
+
@trace.resource({ lifecycle: true })
|
|
136
142
|
export class DataSpaceManager extends Resource {
|
|
137
143
|
public readonly updated = new Event();
|
|
138
144
|
|
|
139
145
|
private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);
|
|
140
146
|
|
|
141
|
-
private readonly _instanceId = PublicKey.random().toHex();
|
|
142
|
-
|
|
143
147
|
private readonly _spaceManager: SpaceManager;
|
|
144
|
-
private readonly _metadataStore:
|
|
145
|
-
private readonly _keyring:
|
|
148
|
+
private readonly _metadataStore: IMetadataStore;
|
|
149
|
+
private readonly _keyring: KeyringApi;
|
|
146
150
|
private readonly _signingContext: SigningContext;
|
|
147
151
|
private readonly _feedStore: FeedStore<FeedMessage>;
|
|
148
152
|
private readonly _echoHost: EchoHost;
|
|
@@ -151,10 +155,10 @@ export class DataSpaceManager extends Resource {
|
|
|
151
155
|
private readonly _edgeHttpClient?: EdgeHttpClient = undefined;
|
|
152
156
|
private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures = undefined;
|
|
153
157
|
private readonly _meshReplicator?: MeshEchoReplicator = undefined;
|
|
154
|
-
private readonly _echoEdgeReplicator?:
|
|
155
|
-
private readonly
|
|
158
|
+
private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;
|
|
159
|
+
private readonly _runtimeProps?: DataSpaceManagerRuntimeProps = undefined;
|
|
156
160
|
|
|
157
|
-
constructor(params:
|
|
161
|
+
constructor(params: DataSpaceManagerProps) {
|
|
158
162
|
super();
|
|
159
163
|
|
|
160
164
|
this._spaceManager = params.spaceManager;
|
|
@@ -169,7 +173,7 @@ export class DataSpaceManager extends Resource {
|
|
|
169
173
|
this._edgeFeatures = params.edgeFeatures;
|
|
170
174
|
this._echoEdgeReplicator = params.echoEdgeReplicator;
|
|
171
175
|
this._edgeHttpClient = params.edgeHttpClient;
|
|
172
|
-
this.
|
|
176
|
+
this._runtimeProps = params.runtimeProps;
|
|
173
177
|
|
|
174
178
|
trace.diagnostic({
|
|
175
179
|
id: 'spaces',
|
|
@@ -179,12 +183,11 @@ export class DataSpaceManager extends Resource {
|
|
|
179
183
|
Array.from(this._spaces.values()).map(async (space) => {
|
|
180
184
|
const rootUrl = space.automergeSpaceState.rootUrl;
|
|
181
185
|
const rootHandle = rootUrl
|
|
182
|
-
? await this._echoHost.
|
|
186
|
+
? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)
|
|
183
187
|
: undefined;
|
|
184
|
-
await rootHandle?.whenReady();
|
|
185
188
|
const rootDoc = rootHandle?.doc();
|
|
186
189
|
|
|
187
|
-
const properties = rootDoc && findInlineObjectOfType(rootDoc,
|
|
190
|
+
const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));
|
|
188
191
|
|
|
189
192
|
return {
|
|
190
193
|
key: space.key.toHex(),
|
|
@@ -212,30 +215,46 @@ export class DataSpaceManager extends Resource {
|
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
@synchronized
|
|
215
|
-
|
|
218
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
219
|
+
protected override async _open(ctx: Context): Promise<void> {
|
|
216
220
|
log('open');
|
|
217
|
-
log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
|
|
218
221
|
log('metadata loaded', { spaces: this._metadataStore.spaces.length });
|
|
219
222
|
|
|
223
|
+
const spacesToActivate: DataSpace[] = [];
|
|
220
224
|
await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {
|
|
221
225
|
try {
|
|
226
|
+
// Tombstoned spaces are never constructed, opened, or replicated.
|
|
227
|
+
if (spaceMetadata.state === SpaceState.SPACE_DELETED || this.isSpaceDeleted(spaceMetadata.key)) {
|
|
228
|
+
log('skipping deleted space', { spaceKey: spaceMetadata.key });
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
222
231
|
log('load space', { spaceMetadata });
|
|
223
|
-
await this._constructSpace(spaceMetadata);
|
|
232
|
+
const space = await this._constructSpace(ctx, spaceMetadata);
|
|
233
|
+
// Track spaces that were previously active for auto-activation (used in dedicated worker mode).
|
|
234
|
+
if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
|
|
235
|
+
spacesToActivate.push(space);
|
|
236
|
+
}
|
|
224
237
|
} catch (err) {
|
|
225
238
|
log.error('Error loading space', { spaceMetadata, err });
|
|
226
239
|
}
|
|
227
240
|
});
|
|
228
241
|
|
|
229
|
-
|
|
242
|
+
// Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
|
|
243
|
+
for (const space of spacesToActivate) {
|
|
244
|
+
log('auto-activating space', { spaceKey: space.key });
|
|
245
|
+
space.activate(ctx).catch((err) => {
|
|
246
|
+
log.error('Error auto-activating space', { spaceKey: space.key, err });
|
|
247
|
+
});
|
|
248
|
+
}
|
|
230
249
|
|
|
231
|
-
|
|
250
|
+
this.updated.emit();
|
|
232
251
|
}
|
|
233
252
|
|
|
234
253
|
@synchronized
|
|
235
|
-
protected override async _close(): Promise<void> {
|
|
254
|
+
protected override async _close(ctx: Context): Promise<void> {
|
|
236
255
|
log('close');
|
|
237
256
|
for (const space of this._spaces.values()) {
|
|
238
|
-
await space.close();
|
|
257
|
+
await space.close(ctx);
|
|
239
258
|
}
|
|
240
259
|
this._spaces.clear();
|
|
241
260
|
}
|
|
@@ -244,10 +263,17 @@ export class DataSpaceManager extends Resource {
|
|
|
244
263
|
* Creates a new space writing the genesis credentials to the control feed.
|
|
245
264
|
*/
|
|
246
265
|
@synchronized
|
|
247
|
-
|
|
248
|
-
|
|
266
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
267
|
+
async createSpace(ctx: Context, options: CreateSpaceOptions = {}): Promise<DataSpace> {
|
|
268
|
+
assertArgument(
|
|
269
|
+
!!options.rootUrl === !!options.documents,
|
|
270
|
+
'options',
|
|
271
|
+
'root url must be required when providing documents',
|
|
272
|
+
);
|
|
249
273
|
|
|
250
274
|
assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
275
|
+
|
|
276
|
+
const tags = options.tags ? Array.from(options.tags) : [];
|
|
251
277
|
const spaceKey = await this._keyring.createKey();
|
|
252
278
|
const controlFeedKey = await this._keyring.createKey();
|
|
253
279
|
const dataFeedKey = await this._keyring.createKey();
|
|
@@ -260,6 +286,7 @@ export class DataSpaceManager extends Resource {
|
|
|
260
286
|
controlFeedKey,
|
|
261
287
|
dataFeedKey,
|
|
262
288
|
state: SpaceState.SPACE_ACTIVE,
|
|
289
|
+
tags,
|
|
263
290
|
};
|
|
264
291
|
|
|
265
292
|
log('creating space...', { spaceId, spaceKey });
|
|
@@ -275,7 +302,18 @@ export class DataSpaceManager extends Resource {
|
|
|
275
302
|
await Promise.all(
|
|
276
303
|
Object.entries(options.documents).map(async ([documentId, data]) => {
|
|
277
304
|
log('creating document...', { documentId });
|
|
278
|
-
|
|
305
|
+
// TODO(dmaretskyi): Broken types -- the bytes get interpreted as CRDT data.
|
|
306
|
+
const newDoc = await this._echoHost.createDoc(data as any as DatabaseDirectory, {
|
|
307
|
+
preserveHistory: true,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// The archived documents might have the spaceKey from the space they were expored from, we need to update it to the new spaceKey.
|
|
311
|
+
if (newDoc.doc().access !== undefined && newDoc.doc().access!.spaceKey !== spaceKey.toHex()) {
|
|
312
|
+
newDoc.change((doc) => {
|
|
313
|
+
doc.access!.spaceKey = spaceKey.toHex();
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
279
317
|
documentIdMapping[documentId as DocumentId] = newDoc.documentId;
|
|
280
318
|
}),
|
|
281
319
|
);
|
|
@@ -286,29 +324,38 @@ export class DataSpaceManager extends Resource {
|
|
|
286
324
|
let root: DatabaseRoot;
|
|
287
325
|
if (options.rootUrl) {
|
|
288
326
|
const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
|
|
289
|
-
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(
|
|
327
|
+
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);
|
|
328
|
+
invariant(rootDocHandle, 'Root document must be available after import.');
|
|
290
329
|
DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
|
|
291
330
|
|
|
292
|
-
root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
331
|
+
root = await this._echoHost.openSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
293
332
|
} else {
|
|
294
|
-
root = await this._echoHost.createSpaceRoot(spaceKey);
|
|
333
|
+
root = await this._echoHost.createSpaceRoot(ctx, spaceKey);
|
|
295
334
|
}
|
|
335
|
+
await this._echoHost.flush(ctx);
|
|
296
336
|
|
|
297
337
|
log('constructing space...', { spaceKey });
|
|
298
338
|
|
|
299
|
-
const space = await this._constructSpace(metadata);
|
|
300
|
-
await space.open();
|
|
339
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
340
|
+
await space.open(ctx);
|
|
301
341
|
|
|
302
342
|
log('adding space...', { spaceKey });
|
|
303
343
|
|
|
304
|
-
const credentials = await spaceGenesis(
|
|
344
|
+
const credentials = await spaceGenesis(
|
|
345
|
+
this._keyring,
|
|
346
|
+
this._signingContext,
|
|
347
|
+
space.inner,
|
|
348
|
+
root.url,
|
|
349
|
+
tags,
|
|
350
|
+
options.membershipPolicy,
|
|
351
|
+
);
|
|
305
352
|
await this._metadataStore.addSpace(metadata);
|
|
306
353
|
|
|
307
354
|
const memberCredential = credentials[1];
|
|
308
355
|
invariant(getCredentialAssertion(memberCredential)['@type'] === 'dxos.halo.credentials.SpaceMember');
|
|
309
356
|
await this._signingContext.recordCredential(memberCredential);
|
|
310
357
|
|
|
311
|
-
await space.initializeDataPipeline();
|
|
358
|
+
await space.initializeDataPipeline(ctx);
|
|
312
359
|
|
|
313
360
|
log('space ready.', { spaceId, spaceKey });
|
|
314
361
|
|
|
@@ -316,86 +363,113 @@ export class DataSpaceManager extends Resource {
|
|
|
316
363
|
return space;
|
|
317
364
|
}
|
|
318
365
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
case SpaceDocVersion.CURRENT: {
|
|
325
|
-
if (!space.databaseRoot.handle.isReady()) {
|
|
326
|
-
log.warn('waiting for space root to be ready', { spaceId: space.id });
|
|
327
|
-
await space.databaseRoot.handle.whenReady();
|
|
328
|
-
}
|
|
329
|
-
const [_, properties] = findInlineObjectOfType(space.databaseRoot.doc()!, TYPE_PROPERTIES) ?? [];
|
|
330
|
-
return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
|
|
331
|
-
}
|
|
332
|
-
case SpaceDocVersion.LEGACY: {
|
|
333
|
-
throw new Error('Legacy space version is not supported');
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
default:
|
|
337
|
-
log.warn('unknown space version', { version: space.databaseRoot.getVersion(), spaceId: space.id });
|
|
338
|
-
return false;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
async createDefaultSpace(): Promise<DataSpace> {
|
|
343
|
-
const space = await this.createSpace();
|
|
344
|
-
const document = await this._getSpaceRootDocument(space);
|
|
345
|
-
|
|
346
|
-
// TODO(dmaretskyi): Better API for low-level data access.
|
|
347
|
-
const properties: ObjectStructure = {
|
|
348
|
-
system: {
|
|
349
|
-
type: encodeReference(getTypeReference(PropertiesType)!),
|
|
350
|
-
},
|
|
351
|
-
data: {
|
|
352
|
-
[DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
|
|
353
|
-
},
|
|
354
|
-
meta: {
|
|
355
|
-
keys: [],
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
const propertiesId = ObjectId.random();
|
|
360
|
-
document.change((doc: DatabaseDirectory) => {
|
|
361
|
-
setDeep(doc, ['objects', propertiesId], properties);
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
await this._echoHost.flush();
|
|
365
|
-
return space;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
|
|
369
|
-
const automergeIndex = space.automergeSpaceState.rootUrl;
|
|
370
|
-
invariant(automergeIndex);
|
|
371
|
-
const document = await this._echoHost.automergeRepo.find<DatabaseDirectory>(automergeIndex as any, FIND_PARAMS);
|
|
372
|
-
await document.whenReady();
|
|
373
|
-
return document;
|
|
374
|
-
}
|
|
375
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Accepts an existing space by joining its swarm and initializing the data pipeline.
|
|
368
|
+
* @param ctx - Caller context for cancellation and tracing.
|
|
369
|
+
* @param opts - Space keys and optional timeframes for catch-up.
|
|
370
|
+
*/
|
|
376
371
|
// TODO(burdon): Rename join space.
|
|
377
372
|
@synchronized
|
|
378
|
-
|
|
373
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
374
|
+
async acceptSpace(ctx: Context, opts: AcceptSpaceOptions): Promise<DataSpace> {
|
|
379
375
|
log('accept space', { opts });
|
|
380
376
|
invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
381
377
|
invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');
|
|
378
|
+
invariant(!this.isSpaceDeleted(opts.spaceKey), 'Cannot accept a deleted space.');
|
|
382
379
|
|
|
380
|
+
const tags = opts.tags ? Array.from(opts.tags) : [];
|
|
383
381
|
const metadata: SpaceMetadata = {
|
|
384
382
|
key: opts.spaceKey,
|
|
385
383
|
genesisFeedKey: opts.genesisFeedKey,
|
|
386
384
|
controlTimeframe: opts.controlTimeframe,
|
|
387
385
|
dataTimeframe: opts.dataTimeframe,
|
|
386
|
+
tags,
|
|
388
387
|
};
|
|
389
388
|
|
|
390
|
-
const space = await this._constructSpace(metadata);
|
|
391
|
-
await space.open();
|
|
389
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
390
|
+
await space.open(ctx);
|
|
392
391
|
await this._metadataStore.addSpace(metadata);
|
|
393
|
-
|
|
392
|
+
// Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as
|
|
393
|
+
// `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline
|
|
394
|
+
// initialization must outlive the invitation flow, and its span must be parented to a
|
|
395
|
+
// long-lived context.
|
|
396
|
+
space.initializeDataPipelineAsync(this._ctx);
|
|
394
397
|
|
|
395
398
|
this.updated.emit();
|
|
396
399
|
return space;
|
|
397
400
|
}
|
|
398
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Whether the space has been tombstoned (soft-deleted). Deleted spaces are never opened or replicated.
|
|
404
|
+
*/
|
|
405
|
+
isSpaceDeleted(spaceKey: PublicKey): boolean {
|
|
406
|
+
// Mirror the deletion predicate used in `_open`: the tombstone list or a persisted SPACE_DELETED state.
|
|
407
|
+
return (
|
|
408
|
+
this._metadataStore.deletedSpaces.some((key) => key.equals(spaceKey)) ||
|
|
409
|
+
this._metadataStore.spaces.some(
|
|
410
|
+
(spaceMetadata) => spaceMetadata.key.equals(spaceKey) && spaceMetadata.state === SpaceState.SPACE_DELETED,
|
|
411
|
+
)
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Tombstones (soft-deletes) a space initiated locally on this device.
|
|
417
|
+
* Records a SpaceDeleted credential in the HALO so the deletion replicates to the user's other devices,
|
|
418
|
+
* then unloads the space locally. Data is not removed until garbage collection (future work).
|
|
419
|
+
*/
|
|
420
|
+
@synchronized
|
|
421
|
+
async markSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {
|
|
422
|
+
if (this.isSpaceDeleted(spaceKey)) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Replicates to the user's other devices via the HALO control feed.
|
|
427
|
+
const credential = await this._signingContext.credentialSigner.createCredential({
|
|
428
|
+
subject: spaceKey,
|
|
429
|
+
assertion: {
|
|
430
|
+
'@type': 'dxos.halo.credentials.SpaceDeleted',
|
|
431
|
+
spaceKey,
|
|
432
|
+
deletedAt: new Date(),
|
|
433
|
+
},
|
|
434
|
+
});
|
|
435
|
+
await this._signingContext.recordCredential(credential);
|
|
436
|
+
|
|
437
|
+
await this._tombstoneSpace(ctx, spaceKey);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Tombstones a space in response to a SpaceDeleted credential replicated from another device.
|
|
442
|
+
* Does not write a credential (one already exists in the HALO).
|
|
443
|
+
*/
|
|
444
|
+
@synchronized
|
|
445
|
+
async handleRemoteSpaceDeleted(ctx: Context, spaceKey: PublicKey): Promise<void> {
|
|
446
|
+
if (this.isSpaceDeleted(spaceKey)) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
await this._tombstoneSpace(ctx, spaceKey);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Persists the tombstone and unloads the space if it is currently loaded.
|
|
455
|
+
* Must be called while holding the DataSpaceManager lock (see callers).
|
|
456
|
+
*/
|
|
457
|
+
private async _tombstoneSpace(ctx: Context, spaceKey: PublicKey): Promise<void> {
|
|
458
|
+
await this._metadataStore.addDeletedSpace(spaceKey);
|
|
459
|
+
|
|
460
|
+
const space = this._spaces.get(spaceKey);
|
|
461
|
+
if (space) {
|
|
462
|
+
// Separate teardown (resource lifecycle) from the terminal state transition.
|
|
463
|
+
if (space.isOpen) {
|
|
464
|
+
await space.close(ctx);
|
|
465
|
+
}
|
|
466
|
+
await space.delete();
|
|
467
|
+
this._spaces.delete(spaceKey);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
this.updated.emit();
|
|
471
|
+
}
|
|
472
|
+
|
|
399
473
|
async admitMember(options: AdmitMemberOptions): Promise<Credential> {
|
|
400
474
|
const space = this._spaceManager.spaces.get(options.spaceKey);
|
|
401
475
|
invariant(space);
|
|
@@ -414,6 +488,7 @@ export class DataSpaceManager extends Resource {
|
|
|
414
488
|
space.spaceState.membershipChainHeads,
|
|
415
489
|
options.profile,
|
|
416
490
|
options.delegationCredentialId,
|
|
491
|
+
space.spaceState.tags,
|
|
417
492
|
);
|
|
418
493
|
|
|
419
494
|
// TODO(dmaretskyi): Refactor.
|
|
@@ -440,8 +515,8 @@ export class DataSpaceManager extends Resource {
|
|
|
440
515
|
);
|
|
441
516
|
}
|
|
442
517
|
|
|
443
|
-
public async requestSpaceAdmissionCredential(spaceKey: PublicKey): Promise<Credential> {
|
|
444
|
-
return this._spaceManager.requestSpaceAdmissionCredential({
|
|
518
|
+
public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {
|
|
519
|
+
return this._spaceManager.requestSpaceAdmissionCredential(ctx, {
|
|
445
520
|
spaceKey,
|
|
446
521
|
identityKey: this._signingContext.identityKey,
|
|
447
522
|
timeout: 15_000,
|
|
@@ -454,7 +529,11 @@ export class DataSpaceManager extends Resource {
|
|
|
454
529
|
});
|
|
455
530
|
}
|
|
456
531
|
|
|
457
|
-
async setSpaceEdgeReplicationSetting(
|
|
532
|
+
async setSpaceEdgeReplicationSetting(
|
|
533
|
+
ctx: Context,
|
|
534
|
+
spaceKey: PublicKey,
|
|
535
|
+
setting: EdgeReplicationSetting,
|
|
536
|
+
): Promise<void> {
|
|
458
537
|
const space = this._spaces.get(spaceKey);
|
|
459
538
|
invariant(space, 'Space not found.');
|
|
460
539
|
|
|
@@ -466,7 +545,7 @@ export class DataSpaceManager extends Resource {
|
|
|
466
545
|
await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
|
|
467
546
|
break;
|
|
468
547
|
case EdgeReplicationSetting.ENABLED:
|
|
469
|
-
await this._echoEdgeReplicator?.connectToSpace(space.id);
|
|
548
|
+
await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);
|
|
470
549
|
break;
|
|
471
550
|
}
|
|
472
551
|
}
|
|
@@ -474,14 +553,14 @@ export class DataSpaceManager extends Resource {
|
|
|
474
553
|
space.stateUpdate.emit();
|
|
475
554
|
}
|
|
476
555
|
|
|
477
|
-
private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
|
|
556
|
+
private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {
|
|
478
557
|
log('construct space', { metadata });
|
|
479
558
|
const gossip = new Gossip({
|
|
480
559
|
localPeerId: this._signingContext.deviceKey,
|
|
481
560
|
});
|
|
482
561
|
const presence = new Presence({
|
|
483
|
-
announceInterval: this.
|
|
484
|
-
offlineTimeout: this.
|
|
562
|
+
announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
|
|
563
|
+
offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
|
|
485
564
|
identityKey: this._signingContext.identityKey,
|
|
486
565
|
gossip,
|
|
487
566
|
});
|
|
@@ -564,17 +643,19 @@ export class DataSpaceManager extends Resource {
|
|
|
564
643
|
},
|
|
565
644
|
},
|
|
566
645
|
cache: metadata.cache,
|
|
646
|
+
tags: metadata.tags,
|
|
567
647
|
edgeConnection: this._edgeConnection,
|
|
568
648
|
edgeHttpClient: this._edgeHttpClient,
|
|
569
649
|
edgeFeatures: this._edgeFeatures,
|
|
570
|
-
activeEdgeNotarizationPollingInterval: this.
|
|
650
|
+
activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,
|
|
571
651
|
});
|
|
572
652
|
dataSpace.postOpen.append(async () => {
|
|
573
653
|
const setting = dataSpace.getEdgeReplicationSetting();
|
|
574
654
|
if (!setting || setting === EdgeReplicationSetting.ENABLED) {
|
|
575
|
-
|
|
655
|
+
// Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.
|
|
656
|
+
await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);
|
|
576
657
|
} else if (this._echoEdgeReplicator) {
|
|
577
|
-
log('not connecting
|
|
658
|
+
log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
|
|
578
659
|
}
|
|
579
660
|
});
|
|
580
661
|
dataSpace.preClose.append(async () => {
|
|
@@ -669,7 +750,7 @@ export class DataSpaceManager extends Resource {
|
|
|
669
750
|
invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
|
|
670
751
|
): Promise<void> {
|
|
671
752
|
const tasks = invitations.map(([credentialId, invitation]) => {
|
|
672
|
-
return this._invitationsManager.createInvitation({
|
|
753
|
+
return this._invitationsManager.createInvitation(this._ctx, {
|
|
673
754
|
type: Invitation.Type.DELEGATED,
|
|
674
755
|
kind: Invitation.Kind.SPACE,
|
|
675
756
|
spaceKey: space.key,
|