@dxos/client-services 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc
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-QCWEHHJW.mjs +24 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KPYVJG6G.mjs → chunk-TUCJORVO.mjs} +2153 -3654
- package/dist/lib/browser/chunk-TUCJORVO.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 +424 -137
- 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 +28 -29
- 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-BBBSS6UL.mjs → chunk-IQLAKNSR.mjs} +2099 -3469
- package/dist/lib/node-esm/chunk-IQLAKNSR.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +424 -137
- 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 +28 -29
- 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 +2 -2
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- 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 +2 -2
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +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 +6 -6
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +8 -7
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +8 -11
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
- 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 +3 -3
- 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 +4 -3
- 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 +59 -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/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +13 -9
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +20 -7
- 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/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 +30 -19
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +26 -9
- 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.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
- 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/level.d.ts.map +1 -1
- 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 +6 -5
- 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 -56
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +8 -5
- package/src/packlets/agents/edge-agent-service.ts +4 -2
- package/src/packlets/devices/devices-service.test.ts +0 -1
- package/src/packlets/devtools/devtools.ts +2 -3
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/diagnostics/index.ts +1 -1
- package/src/packlets/identity/authenticator.ts +2 -2
- package/src/packlets/identity/contacts-service.ts +0 -1
- package/src/packlets/identity/identity-manager.test.ts +5 -5
- package/src/packlets/identity/identity-manager.ts +23 -22
- package/src/packlets/identity/identity-recovery-manager.ts +22 -18
- package/src/packlets/identity/identity-service.test.ts +6 -27
- package/src/packlets/identity/identity-service.ts +13 -81
- package/src/packlets/identity/identity.test.ts +2 -2
- package/src/packlets/identity/identity.ts +11 -34
- package/src/packlets/invitations/device-invitation-protocol.ts +8 -7
- 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 +40 -15
- 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 +11 -16
- 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 +340 -0
- package/src/packlets/services/feed-syncer.ts +377 -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 +153 -61
- package/src/packlets/services/service-host.test.ts +8 -8
- package/src/packlets/services/service-host.ts +70 -40
- package/src/packlets/services/service-registry.test.ts +0 -1
- 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 +111 -0
- package/src/packlets/space-export/serialized-space-writer.ts +252 -0
- package/src/packlets/space-export/space-archive-reader.ts +64 -3
- package/src/packlets/space-export/space-archive-writer.ts +41 -3
- package/src/packlets/space-export/space-archive.test.ts +461 -0
- package/src/packlets/spaces/data-space-manager.test.ts +79 -13
- package/src/packlets/spaces/data-space-manager.ts +108 -120
- package/src/packlets/spaces/data-space.ts +64 -36
- package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
- package/src/packlets/spaces/edge-feed-replicator.ts +11 -9
- package/src/packlets/spaces/epoch-migrations.ts +6 -5
- package/src/packlets/spaces/genesis.ts +6 -1
- 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 +124 -24
- package/src/packlets/storage/storage.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +10 -6
- package/src/packlets/testing/test-builder.ts +36 -10
- package/src/packlets/worker/worker-runtime.ts +188 -17
- package/src/packlets/worker/worker-session.ts +12 -18
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-KPYVJG6G.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-BBBSS6UL.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,14 +15,13 @@ import {
|
|
|
15
15
|
createAdmissionCredentials,
|
|
16
16
|
getCredentialAssertion,
|
|
17
17
|
} from '@dxos/credentials';
|
|
18
|
-
import {
|
|
18
|
+
import { Type } from '@dxos/echo';
|
|
19
19
|
import {
|
|
20
20
|
AuthStatus,
|
|
21
21
|
CredentialServerExtension,
|
|
22
22
|
DatabaseRoot,
|
|
23
|
-
type EchoEdgeReplicator,
|
|
24
23
|
type EchoHost,
|
|
25
|
-
|
|
24
|
+
type EdgeAutomergeReplicator,
|
|
26
25
|
type MeshEchoReplicator,
|
|
27
26
|
type MetadataStore,
|
|
28
27
|
type Space,
|
|
@@ -31,45 +30,40 @@ import {
|
|
|
31
30
|
type SpaceProtocolSession,
|
|
32
31
|
findInlineObjectOfType,
|
|
33
32
|
} from '@dxos/echo-pipeline';
|
|
34
|
-
import {
|
|
35
|
-
type DatabaseDirectory,
|
|
36
|
-
type ObjectStructure,
|
|
37
|
-
SpaceDocVersion,
|
|
38
|
-
createIdFromSpaceKey,
|
|
39
|
-
encodeReference,
|
|
40
|
-
} from '@dxos/echo-protocol';
|
|
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
37
|
import { type Keyring } 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,9 +99,10 @@ 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
107
|
metadataStore: MetadataStore;
|
|
110
108
|
keyring: Keyring;
|
|
@@ -115,31 +113,37 @@ 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
148
|
private readonly _metadataStore: MetadataStore;
|
|
145
149
|
private readonly _keyring: Keyring;
|
|
@@ -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,41 @@ 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 {
|
|
222
226
|
log('load space', { spaceMetadata });
|
|
223
|
-
await this._constructSpace(spaceMetadata);
|
|
227
|
+
const space = await this._constructSpace(ctx, spaceMetadata);
|
|
228
|
+
// Track spaces that were previously active for auto-activation (used in dedicated worker mode).
|
|
229
|
+
if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
|
|
230
|
+
spacesToActivate.push(space);
|
|
231
|
+
}
|
|
224
232
|
} catch (err) {
|
|
225
233
|
log.error('Error loading space', { spaceMetadata, err });
|
|
226
234
|
}
|
|
227
235
|
});
|
|
228
236
|
|
|
229
|
-
|
|
237
|
+
// Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
|
|
238
|
+
for (const space of spacesToActivate) {
|
|
239
|
+
log('auto-activating space', { spaceKey: space.key });
|
|
240
|
+
space.activate(ctx).catch((err) => {
|
|
241
|
+
log.error('Error auto-activating space', { spaceKey: space.key, err });
|
|
242
|
+
});
|
|
243
|
+
}
|
|
230
244
|
|
|
231
|
-
|
|
245
|
+
this.updated.emit();
|
|
232
246
|
}
|
|
233
247
|
|
|
234
248
|
@synchronized
|
|
235
|
-
protected override async _close(): Promise<void> {
|
|
249
|
+
protected override async _close(ctx: Context): Promise<void> {
|
|
236
250
|
log('close');
|
|
237
251
|
for (const space of this._spaces.values()) {
|
|
238
|
-
await space.close();
|
|
252
|
+
await space.close(ctx);
|
|
239
253
|
}
|
|
240
254
|
this._spaces.clear();
|
|
241
255
|
}
|
|
@@ -244,7 +258,8 @@ export class DataSpaceManager extends Resource {
|
|
|
244
258
|
* Creates a new space writing the genesis credentials to the control feed.
|
|
245
259
|
*/
|
|
246
260
|
@synchronized
|
|
247
|
-
|
|
261
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
262
|
+
async createSpace(ctx: Context, options: CreateSpaceOptions = {}): Promise<DataSpace> {
|
|
248
263
|
assertArgument(
|
|
249
264
|
!!options.rootUrl === !!options.documents,
|
|
250
265
|
'options',
|
|
@@ -252,6 +267,8 @@ export class DataSpaceManager extends Resource {
|
|
|
252
267
|
);
|
|
253
268
|
|
|
254
269
|
assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
270
|
+
|
|
271
|
+
const tags = options.tags ? Array.from(options.tags) : [];
|
|
255
272
|
const spaceKey = await this._keyring.createKey();
|
|
256
273
|
const controlFeedKey = await this._keyring.createKey();
|
|
257
274
|
const dataFeedKey = await this._keyring.createKey();
|
|
@@ -264,6 +281,7 @@ export class DataSpaceManager extends Resource {
|
|
|
264
281
|
controlFeedKey,
|
|
265
282
|
dataFeedKey,
|
|
266
283
|
state: SpaceState.SPACE_ACTIVE,
|
|
284
|
+
tags,
|
|
267
285
|
};
|
|
268
286
|
|
|
269
287
|
log('creating space...', { spaceId, spaceKey });
|
|
@@ -301,30 +319,38 @@ export class DataSpaceManager extends Resource {
|
|
|
301
319
|
let root: DatabaseRoot;
|
|
302
320
|
if (options.rootUrl) {
|
|
303
321
|
const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
|
|
304
|
-
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(
|
|
322
|
+
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);
|
|
323
|
+
invariant(rootDocHandle, 'Root document must be available after import.');
|
|
305
324
|
DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
|
|
306
325
|
|
|
307
|
-
root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
326
|
+
root = await this._echoHost.openSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
308
327
|
} else {
|
|
309
|
-
root = await this._echoHost.createSpaceRoot(spaceKey);
|
|
328
|
+
root = await this._echoHost.createSpaceRoot(ctx, spaceKey);
|
|
310
329
|
}
|
|
311
|
-
await this._echoHost.flush();
|
|
330
|
+
await this._echoHost.flush(ctx);
|
|
312
331
|
|
|
313
332
|
log('constructing space...', { spaceKey });
|
|
314
333
|
|
|
315
|
-
const space = await this._constructSpace(metadata);
|
|
316
|
-
await space.open();
|
|
334
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
335
|
+
await space.open(ctx);
|
|
317
336
|
|
|
318
337
|
log('adding space...', { spaceKey });
|
|
319
338
|
|
|
320
|
-
const credentials = await spaceGenesis(
|
|
339
|
+
const credentials = await spaceGenesis(
|
|
340
|
+
this._keyring,
|
|
341
|
+
this._signingContext,
|
|
342
|
+
space.inner,
|
|
343
|
+
root.url,
|
|
344
|
+
tags,
|
|
345
|
+
options.membershipPolicy,
|
|
346
|
+
);
|
|
321
347
|
await this._metadataStore.addSpace(metadata);
|
|
322
348
|
|
|
323
349
|
const memberCredential = credentials[1];
|
|
324
350
|
invariant(getCredentialAssertion(memberCredential)['@type'] === 'dxos.halo.credentials.SpaceMember');
|
|
325
351
|
await this._signingContext.recordCredential(memberCredential);
|
|
326
352
|
|
|
327
|
-
await space.initializeDataPipeline();
|
|
353
|
+
await space.initializeDataPipeline(ctx);
|
|
328
354
|
|
|
329
355
|
log('space ready.', { spaceId, spaceKey });
|
|
330
356
|
|
|
@@ -332,81 +358,36 @@ export class DataSpaceManager extends Resource {
|
|
|
332
358
|
return space;
|
|
333
359
|
}
|
|
334
360
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
case SpaceDocVersion.CURRENT: {
|
|
341
|
-
if (!space.databaseRoot.handle.isReady()) {
|
|
342
|
-
log.warn('waiting for space root to be ready', { spaceId: space.id });
|
|
343
|
-
await space.databaseRoot.handle.whenReady();
|
|
344
|
-
}
|
|
345
|
-
const [_, properties] = findInlineObjectOfType(space.databaseRoot.doc()!, TYPE_PROPERTIES) ?? [];
|
|
346
|
-
return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
|
|
347
|
-
}
|
|
348
|
-
case SpaceDocVersion.LEGACY: {
|
|
349
|
-
throw new Error('Legacy space version is not supported');
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
default:
|
|
353
|
-
log.warn('unknown space version', { version: space.databaseRoot.getVersion(), spaceId: space.id });
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async createDefaultSpace(): Promise<DataSpace> {
|
|
359
|
-
const space = await this.createSpace();
|
|
360
|
-
const document = await this._getSpaceRootDocument(space);
|
|
361
|
-
|
|
362
|
-
// TODO(dmaretskyi): Better API for low-level data access.
|
|
363
|
-
const properties: ObjectStructure = {
|
|
364
|
-
system: {
|
|
365
|
-
type: encodeReference(getTypeReference(PropertiesType)!),
|
|
366
|
-
},
|
|
367
|
-
data: {
|
|
368
|
-
[DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
|
|
369
|
-
},
|
|
370
|
-
meta: {
|
|
371
|
-
keys: [],
|
|
372
|
-
},
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
const propertiesId = ObjectId.random();
|
|
376
|
-
document.change((doc: DatabaseDirectory) => {
|
|
377
|
-
setDeep(doc, ['objects', propertiesId], properties);
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
await this._echoHost.flush();
|
|
381
|
-
return space;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
|
|
385
|
-
const automergeIndex = space.automergeSpaceState.rootUrl;
|
|
386
|
-
invariant(automergeIndex);
|
|
387
|
-
const document = await this._echoHost.automergeRepo.find<DatabaseDirectory>(automergeIndex as any, FIND_PARAMS);
|
|
388
|
-
await document.whenReady();
|
|
389
|
-
return document;
|
|
390
|
-
}
|
|
391
|
-
|
|
361
|
+
/**
|
|
362
|
+
* Accepts an existing space by joining its swarm and initializing the data pipeline.
|
|
363
|
+
* @param ctx - Caller context for cancellation and tracing.
|
|
364
|
+
* @param opts - Space keys and optional timeframes for catch-up.
|
|
365
|
+
*/
|
|
392
366
|
// TODO(burdon): Rename join space.
|
|
393
367
|
@synchronized
|
|
394
|
-
|
|
368
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
369
|
+
async acceptSpace(ctx: Context, opts: AcceptSpaceOptions): Promise<DataSpace> {
|
|
395
370
|
log('accept space', { opts });
|
|
396
371
|
invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
397
372
|
invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');
|
|
398
373
|
|
|
374
|
+
const tags = opts.tags ? Array.from(opts.tags) : [];
|
|
399
375
|
const metadata: SpaceMetadata = {
|
|
400
376
|
key: opts.spaceKey,
|
|
401
377
|
genesisFeedKey: opts.genesisFeedKey,
|
|
402
378
|
controlTimeframe: opts.controlTimeframe,
|
|
403
379
|
dataTimeframe: opts.dataTimeframe,
|
|
380
|
+
tags,
|
|
404
381
|
};
|
|
405
382
|
|
|
406
|
-
const space = await this._constructSpace(metadata);
|
|
407
|
-
await space.open();
|
|
383
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
384
|
+
await space.open(ctx);
|
|
408
385
|
await this._metadataStore.addSpace(metadata);
|
|
409
|
-
|
|
386
|
+
// Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as
|
|
387
|
+
// `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline
|
|
388
|
+
// initialization must outlive the invitation flow, and its span must be parented to a
|
|
389
|
+
// long-lived context.
|
|
390
|
+
space.initializeDataPipelineAsync(this._ctx);
|
|
410
391
|
|
|
411
392
|
this.updated.emit();
|
|
412
393
|
return space;
|
|
@@ -430,6 +411,7 @@ export class DataSpaceManager extends Resource {
|
|
|
430
411
|
space.spaceState.membershipChainHeads,
|
|
431
412
|
options.profile,
|
|
432
413
|
options.delegationCredentialId,
|
|
414
|
+
space.spaceState.tags,
|
|
433
415
|
);
|
|
434
416
|
|
|
435
417
|
// TODO(dmaretskyi): Refactor.
|
|
@@ -456,8 +438,8 @@ export class DataSpaceManager extends Resource {
|
|
|
456
438
|
);
|
|
457
439
|
}
|
|
458
440
|
|
|
459
|
-
public async requestSpaceAdmissionCredential(spaceKey: PublicKey): Promise<Credential> {
|
|
460
|
-
return this._spaceManager.requestSpaceAdmissionCredential({
|
|
441
|
+
public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {
|
|
442
|
+
return this._spaceManager.requestSpaceAdmissionCredential(ctx, {
|
|
461
443
|
spaceKey,
|
|
462
444
|
identityKey: this._signingContext.identityKey,
|
|
463
445
|
timeout: 15_000,
|
|
@@ -470,7 +452,11 @@ export class DataSpaceManager extends Resource {
|
|
|
470
452
|
});
|
|
471
453
|
}
|
|
472
454
|
|
|
473
|
-
async setSpaceEdgeReplicationSetting(
|
|
455
|
+
async setSpaceEdgeReplicationSetting(
|
|
456
|
+
ctx: Context,
|
|
457
|
+
spaceKey: PublicKey,
|
|
458
|
+
setting: EdgeReplicationSetting,
|
|
459
|
+
): Promise<void> {
|
|
474
460
|
const space = this._spaces.get(spaceKey);
|
|
475
461
|
invariant(space, 'Space not found.');
|
|
476
462
|
|
|
@@ -482,7 +468,7 @@ export class DataSpaceManager extends Resource {
|
|
|
482
468
|
await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
|
|
483
469
|
break;
|
|
484
470
|
case EdgeReplicationSetting.ENABLED:
|
|
485
|
-
await this._echoEdgeReplicator?.connectToSpace(space.id);
|
|
471
|
+
await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);
|
|
486
472
|
break;
|
|
487
473
|
}
|
|
488
474
|
}
|
|
@@ -490,14 +476,14 @@ export class DataSpaceManager extends Resource {
|
|
|
490
476
|
space.stateUpdate.emit();
|
|
491
477
|
}
|
|
492
478
|
|
|
493
|
-
private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
|
|
479
|
+
private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {
|
|
494
480
|
log('construct space', { metadata });
|
|
495
481
|
const gossip = new Gossip({
|
|
496
482
|
localPeerId: this._signingContext.deviceKey,
|
|
497
483
|
});
|
|
498
484
|
const presence = new Presence({
|
|
499
|
-
announceInterval: this.
|
|
500
|
-
offlineTimeout: this.
|
|
485
|
+
announceInterval: this._runtimeProps?.spaceMemberPresenceAnnounceInterval ?? PRESENCE_ANNOUNCE_INTERVAL,
|
|
486
|
+
offlineTimeout: this._runtimeProps?.spaceMemberPresenceOfflineTimeout ?? PRESENCE_OFFLINE_TIMEOUT,
|
|
501
487
|
identityKey: this._signingContext.identityKey,
|
|
502
488
|
gossip,
|
|
503
489
|
});
|
|
@@ -580,17 +566,19 @@ export class DataSpaceManager extends Resource {
|
|
|
580
566
|
},
|
|
581
567
|
},
|
|
582
568
|
cache: metadata.cache,
|
|
569
|
+
tags: metadata.tags,
|
|
583
570
|
edgeConnection: this._edgeConnection,
|
|
584
571
|
edgeHttpClient: this._edgeHttpClient,
|
|
585
572
|
edgeFeatures: this._edgeFeatures,
|
|
586
|
-
activeEdgeNotarizationPollingInterval: this.
|
|
573
|
+
activeEdgeNotarizationPollingInterval: this._runtimeProps?.activeEdgeNotarizationPollingInterval,
|
|
587
574
|
});
|
|
588
575
|
dataSpace.postOpen.append(async () => {
|
|
589
576
|
const setting = dataSpace.getEdgeReplicationSetting();
|
|
590
577
|
if (!setting || setting === EdgeReplicationSetting.ENABLED) {
|
|
591
|
-
|
|
578
|
+
// Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.
|
|
579
|
+
await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);
|
|
592
580
|
} else if (this._echoEdgeReplicator) {
|
|
593
|
-
log('not connecting
|
|
581
|
+
log('not connecting edge replicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
|
|
594
582
|
}
|
|
595
583
|
});
|
|
596
584
|
dataSpace.preClose.append(async () => {
|
|
@@ -685,7 +673,7 @@ export class DataSpaceManager extends Resource {
|
|
|
685
673
|
invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
|
|
686
674
|
): Promise<void> {
|
|
687
675
|
const tasks = invitations.map(([credentialId, invitation]) => {
|
|
688
|
-
return this._invitationsManager.createInvitation({
|
|
676
|
+
return this._invitationsManager.createInvitation(this._ctx, {
|
|
689
677
|
type: Invitation.Type.DELEGATED,
|
|
690
678
|
kind: Invitation.Kind.SPACE,
|
|
691
679
|
spaceKey: space.key,
|