@dxos/client-services 0.6.12 → 0.6.13-main.09887cd
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/{chunk-TOAILL4T.mjs → chunk-XOKN3TE7.mjs} +5890 -5165
- package/dist/lib/browser/chunk-XOKN3TE7.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3 -3
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +12 -7
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-H6C4XY6B.cjs → chunk-IFHGVXW2.cjs} +5922 -5201
- package/dist/lib/node/chunk-IFHGVXW2.cjs.map +7 -0
- package/dist/lib/node/index.cjs +46 -46
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +18 -13
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node-esm/chunk-FTEPRZ23.mjs +8441 -0
- package/dist/lib/node-esm/chunk-FTEPRZ23.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +416 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/testing/index.mjs +424 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts +2 -0
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts.map +1 -0
- 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 +25 -9
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +11 -3
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- 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 +30 -0
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts +2 -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 +2 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts +19 -0
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +8 -8
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +10 -9
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +1 -0
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +6 -3
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +4 -3
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +3 -0
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts +2 -0
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts.map +1 -0
- 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/notarization-plugin.d.ts +31 -6
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +1 -2
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts +3 -0
- package/dist/types/src/testing/setup.d.ts.map +1 -0
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/package.json +43 -39
- package/src/packlets/devices/devices-service.test.ts +4 -5
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -0
- package/src/packlets/identity/{authenticator.test.ts → authenticator.node.test.ts} +2 -3
- package/src/packlets/identity/authenticator.ts +5 -2
- package/src/packlets/identity/contacts-service.ts +1 -1
- package/src/packlets/identity/identity-manager.test.ts +31 -16
- package/src/packlets/identity/identity-manager.ts +47 -31
- package/src/packlets/identity/identity-service.test.ts +4 -8
- package/src/packlets/identity/identity.test.ts +130 -239
- package/src/packlets/identity/identity.ts +56 -17
- package/src/packlets/invitations/device-invitation-protocol.test.ts +7 -4
- package/src/packlets/invitations/device-invitation-protocol.ts +5 -1
- package/src/packlets/invitations/edge-invitation-handler.ts +184 -0
- package/src/packlets/invitations/invitation-guest-extenstion.ts +8 -4
- package/src/packlets/invitations/invitation-host-extension.ts +8 -7
- package/src/packlets/invitations/invitation-state.ts +111 -0
- package/src/packlets/invitations/invitations-handler.test.ts +16 -9
- package/src/packlets/invitations/invitations-handler.ts +23 -92
- package/src/packlets/invitations/space-invitation-protocol.test.ts +4 -3
- package/src/packlets/invitations/space-invitation-protocol.ts +4 -0
- package/src/packlets/logging/logging.test.ts +1 -2
- package/src/packlets/network/network-service.test.ts +2 -3
- package/src/packlets/services/service-context.test.ts +3 -1
- package/src/packlets/services/service-context.ts +93 -37
- package/src/packlets/services/service-host.test.ts +8 -12
- package/src/packlets/services/service-host.ts +8 -6
- package/src/packlets/services/service-registry.test.ts +1 -2
- package/src/packlets/spaces/data-space-manager.test.ts +2 -2
- package/src/packlets/spaces/data-space-manager.ts +40 -5
- package/src/packlets/spaces/data-space.ts +35 -6
- package/src/packlets/spaces/edge-feed-replicator.test.ts +253 -0
- package/src/packlets/spaces/edge-feed-replicator.ts +80 -22
- package/src/packlets/spaces/epoch-migrations.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +10 -7
- package/src/packlets/spaces/notarization-plugin.ts +169 -29
- package/src/packlets/spaces/spaces-service.test.ts +5 -9
- package/src/packlets/spaces/spaces-service.ts +6 -1
- package/src/packlets/storage/storage.ts +0 -1
- package/src/packlets/system/system-service.test.ts +1 -2
- package/src/packlets/testing/test-builder.ts +7 -4
- package/src/packlets/worker/worker-runtime.ts +2 -2
- package/src/testing/setup.ts +11 -0
- package/src/version.ts +1 -5
- package/dist/lib/browser/chunk-TOAILL4T.mjs.map +0 -7
- package/dist/lib/node/chunk-H6C4XY6B.cjs.map +0 -7
- package/dist/types/src/packlets/identity/authenticator.test.d.ts +0 -2
- package/dist/types/src/packlets/identity/authenticator.test.d.ts.map +0 -1
- package/dist/types/src/packlets/services/automerge-host.test.d.ts +0 -2
- package/dist/types/src/packlets/services/automerge-host.test.d.ts.map +0 -1
- package/src/packlets/services/automerge-host.test.ts +0 -60
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { expect } from '
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { log, LogLevel } from '@dxos/log';
|
|
9
9
|
import { type LogEntry } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
-
import { beforeEach, describe, test } from '@dxos/test';
|
|
11
10
|
|
|
12
11
|
import { LoggingServiceImpl } from './logging-service';
|
|
13
12
|
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { expect } from '
|
|
5
|
+
import { afterEach, onTestFinished, beforeEach, describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { type NetworkService, ConnectionState } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
-
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
11
10
|
|
|
12
11
|
import { NetworkServiceImpl } from './network-service';
|
|
13
12
|
import { type ServiceContext } from '../services';
|
|
@@ -41,7 +40,7 @@ describe('NetworkService', () => {
|
|
|
41
40
|
query.subscribe(({ swarm }) => {
|
|
42
41
|
result.wake(swarm);
|
|
43
42
|
});
|
|
44
|
-
|
|
43
|
+
onTestFinished(() => query.close());
|
|
45
44
|
expect(await result.wait()).to.equal(ConnectionState.ONLINE);
|
|
46
45
|
|
|
47
46
|
result = new Trigger<ConnectionState | undefined>();
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
5
7
|
import { MemorySignalManagerContext, MemorySignalManager } from '@dxos/messaging';
|
|
6
8
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
7
|
-
import {
|
|
9
|
+
import { openAndClose } from '@dxos/test-utils';
|
|
8
10
|
|
|
9
11
|
import { createServiceContext, performInvitation } from '../testing';
|
|
10
12
|
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Trigger } from '@dxos/async';
|
|
5
|
+
import { Mutex, Trigger } from '@dxos/async';
|
|
6
6
|
import { Context, Resource } from '@dxos/context';
|
|
7
7
|
import { getCredentialAssertion, type CredentialProcessor } from '@dxos/credentials';
|
|
8
|
-
import { failUndefined } from '@dxos/debug';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
import { failUndefined, warnAfterTimeout } from '@dxos/debug';
|
|
9
|
+
import {
|
|
10
|
+
EchoEdgeReplicator,
|
|
11
|
+
EchoHost,
|
|
12
|
+
MeshEchoReplicator,
|
|
13
|
+
MetadataStore,
|
|
14
|
+
SpaceManager,
|
|
15
|
+
valueEncoding,
|
|
16
|
+
} from '@dxos/echo-pipeline';
|
|
17
|
+
import { createChainEdgeIdentity, createEphemeralEdgeIdentity } from '@dxos/edge-client';
|
|
18
|
+
import type { EdgeHttpClient, EdgeConnection, EdgeIdentity } from '@dxos/edge-client';
|
|
12
19
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
13
20
|
import { invariant } from '@dxos/invariant';
|
|
14
21
|
import { Keyring } from '@dxos/keyring';
|
|
@@ -23,7 +30,6 @@ import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
|
23
30
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
24
31
|
import { type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
25
32
|
import { type Storage } from '@dxos/random-access-storage';
|
|
26
|
-
import type { TeleportParams } from '@dxos/teleport';
|
|
27
33
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
28
34
|
import { trace as Trace } from '@dxos/tracing';
|
|
29
35
|
import { safeInstanceof } from '@dxos/util';
|
|
@@ -31,11 +37,12 @@ import { safeInstanceof } from '@dxos/util';
|
|
|
31
37
|
import {
|
|
32
38
|
IdentityManager,
|
|
33
39
|
type CreateIdentityOptions,
|
|
34
|
-
type
|
|
40
|
+
type IdentityManagerParams,
|
|
35
41
|
type JoinIdentityParams,
|
|
36
42
|
} from '../identity';
|
|
37
43
|
import {
|
|
38
44
|
DeviceInvitationProtocol,
|
|
45
|
+
type InvitationConnectionParams,
|
|
39
46
|
InvitationsHandler,
|
|
40
47
|
InvitationsManager,
|
|
41
48
|
SpaceInvitationProtocol,
|
|
@@ -43,9 +50,12 @@ import {
|
|
|
43
50
|
} from '../invitations';
|
|
44
51
|
import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
|
|
45
52
|
|
|
46
|
-
export type ServiceContextRuntimeParams =
|
|
53
|
+
export type ServiceContextRuntimeParams = Pick<
|
|
54
|
+
IdentityManagerParams,
|
|
55
|
+
'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'
|
|
56
|
+
> &
|
|
47
57
|
DataSpaceManagerRuntimeParams & {
|
|
48
|
-
invitationConnectionDefaultParams?:
|
|
58
|
+
invitationConnectionDefaultParams?: InvitationConnectionParams;
|
|
49
59
|
disableP2pReplication?: boolean;
|
|
50
60
|
};
|
|
51
61
|
/**
|
|
@@ -56,6 +66,8 @@ export type ServiceContextRuntimeParams = IdentityManagerRuntimeParams &
|
|
|
56
66
|
@safeInstanceof('dxos.client-services.ServiceContext')
|
|
57
67
|
@Trace.resource()
|
|
58
68
|
export class ServiceContext extends Resource {
|
|
69
|
+
private readonly _edgeIdentityUpdateMutex = new Mutex();
|
|
70
|
+
|
|
59
71
|
public readonly initialized = new Trigger();
|
|
60
72
|
public readonly metadataStore: MetadataStore;
|
|
61
73
|
public readonly blobStore: BlobStore;
|
|
@@ -87,6 +99,7 @@ export class ServiceContext extends Resource {
|
|
|
87
99
|
public readonly networkManager: SwarmNetworkManager,
|
|
88
100
|
public readonly signalManager: SignalManager,
|
|
89
101
|
private readonly _edgeConnection: EdgeConnection | undefined,
|
|
102
|
+
private readonly _edgeHttpClient: EdgeHttpClient | undefined,
|
|
90
103
|
public readonly _runtimeParams?: ServiceContextRuntimeParams,
|
|
91
104
|
private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures,
|
|
92
105
|
) {
|
|
@@ -116,32 +129,16 @@ export class ServiceContext extends Resource {
|
|
|
116
129
|
disableP2pReplication: this._runtimeParams?.disableP2pReplication,
|
|
117
130
|
});
|
|
118
131
|
|
|
119
|
-
this.identityManager = new IdentityManager(
|
|
120
|
-
this.metadataStore,
|
|
121
|
-
this.keyring,
|
|
122
|
-
this.feedStore,
|
|
123
|
-
this.spaceManager,
|
|
124
|
-
this._runtimeParams
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
identity: identity.identityKey.toHex(),
|
|
130
|
-
oldIdentity: this._edgeConnection.identityKey,
|
|
131
|
-
swarms: this.networkManager.topics,
|
|
132
|
-
});
|
|
133
|
-
this._edgeConnection.setIdentity({
|
|
134
|
-
peerKey: identity.deviceKey.toHex(),
|
|
135
|
-
identityKey: identity.identityKey.toHex(),
|
|
136
|
-
});
|
|
137
|
-
this.networkManager.setPeerInfo({
|
|
138
|
-
identityKey: identity.identityKey.toHex(),
|
|
139
|
-
peerKey: identity.deviceKey.toHex(),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
);
|
|
132
|
+
this.identityManager = new IdentityManager({
|
|
133
|
+
metadataStore: this.metadataStore,
|
|
134
|
+
keyring: this.keyring,
|
|
135
|
+
feedStore: this.feedStore,
|
|
136
|
+
spaceManager: this.spaceManager,
|
|
137
|
+
devicePresenceOfflineTimeout: this._runtimeParams?.devicePresenceOfflineTimeout,
|
|
138
|
+
devicePresenceAnnounceInterval: this._runtimeParams?.devicePresenceAnnounceInterval,
|
|
139
|
+
edgeConnection: this._edgeConnection,
|
|
140
|
+
edgeFeatures: this._edgeFeatures,
|
|
141
|
+
});
|
|
145
142
|
|
|
146
143
|
this.echoHost = new EchoHost({ kv: this.level });
|
|
147
144
|
|
|
@@ -149,6 +146,7 @@ export class ServiceContext extends Resource {
|
|
|
149
146
|
|
|
150
147
|
this.invitations = new InvitationsHandler(
|
|
151
148
|
this.networkManager, //
|
|
149
|
+
this._edgeHttpClient,
|
|
152
150
|
_runtimeParams?.invitationConnectionDefaultParams,
|
|
153
151
|
);
|
|
154
152
|
this.invitationsManager = new InvitationsManager(
|
|
@@ -185,6 +183,11 @@ export class ServiceContext extends Resource {
|
|
|
185
183
|
|
|
186
184
|
log('opening...');
|
|
187
185
|
log.trace('dxos.sdk.service-context.open', trace.begin({ id: this._instanceId }));
|
|
186
|
+
|
|
187
|
+
await this.identityManager.open(ctx);
|
|
188
|
+
|
|
189
|
+
await this._setNetworkIdentity();
|
|
190
|
+
|
|
188
191
|
await this._edgeConnection?.open();
|
|
189
192
|
await this.signalManager.open();
|
|
190
193
|
await this.networkManager.open();
|
|
@@ -200,9 +203,9 @@ export class ServiceContext extends Resource {
|
|
|
200
203
|
|
|
201
204
|
await this.metadataStore.load();
|
|
202
205
|
await this.spaceManager.open();
|
|
203
|
-
await this.identityManager.open(ctx);
|
|
204
206
|
|
|
205
207
|
if (this.identityManager.identity) {
|
|
208
|
+
await this.identityManager.identity.joinNetwork();
|
|
206
209
|
await this._initialize(ctx);
|
|
207
210
|
}
|
|
208
211
|
|
|
@@ -234,6 +237,8 @@ export class ServiceContext extends Resource {
|
|
|
234
237
|
|
|
235
238
|
async createIdentity(params: CreateIdentityOptions = {}) {
|
|
236
239
|
const identity = await this.identityManager.createIdentity(params);
|
|
240
|
+
await this._setNetworkIdentity();
|
|
241
|
+
await identity.joinNetwork();
|
|
237
242
|
await this._initialize(new Context());
|
|
238
243
|
return identity;
|
|
239
244
|
}
|
|
@@ -255,7 +260,10 @@ export class ServiceContext extends Resource {
|
|
|
255
260
|
}
|
|
256
261
|
|
|
257
262
|
private async _acceptIdentity(params: JoinIdentityParams) {
|
|
258
|
-
const identity = await this.identityManager.
|
|
263
|
+
const { identity, identityRecord } = await this.identityManager.prepareIdentity(params);
|
|
264
|
+
await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential! });
|
|
265
|
+
await identity.joinNetwork();
|
|
266
|
+
await this.identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);
|
|
259
267
|
await this._initialize(new Context());
|
|
260
268
|
return identity;
|
|
261
269
|
}
|
|
@@ -292,6 +300,7 @@ export class ServiceContext extends Resource {
|
|
|
292
300
|
echoHost: this.echoHost,
|
|
293
301
|
invitationsManager: this.invitationsManager,
|
|
294
302
|
edgeConnection: this._edgeConnection,
|
|
303
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
295
304
|
echoEdgeReplicator: this._echoEdgeReplicator,
|
|
296
305
|
meshReplicator: this._meshReplicator,
|
|
297
306
|
runtimeParams: this._runtimeParams as DataSpaceManagerRuntimeParams,
|
|
@@ -338,4 +347,51 @@ export class ServiceContext extends Resource {
|
|
|
338
347
|
|
|
339
348
|
await identity.space.spaceState.addCredentialProcessor(this._deviceSpaceSync);
|
|
340
349
|
}
|
|
350
|
+
|
|
351
|
+
private async _setNetworkIdentity(params?: { deviceCredential: Credential }) {
|
|
352
|
+
using _ = await this._edgeIdentityUpdateMutex.acquire();
|
|
353
|
+
|
|
354
|
+
let edgeIdentity: EdgeIdentity;
|
|
355
|
+
const identity = this.identityManager.identity;
|
|
356
|
+
if (identity) {
|
|
357
|
+
log.info('Setting identity on edge connection', {
|
|
358
|
+
identity: identity.identityKey.toHex(),
|
|
359
|
+
swarms: this.networkManager.topics,
|
|
360
|
+
});
|
|
361
|
+
if (params?.deviceCredential) {
|
|
362
|
+
edgeIdentity = await createChainEdgeIdentity(
|
|
363
|
+
identity.signer,
|
|
364
|
+
identity.identityKey,
|
|
365
|
+
identity.deviceKey,
|
|
366
|
+
{ credential: params.deviceCredential },
|
|
367
|
+
[], // TODO(dmaretskyi): Service access credentials.
|
|
368
|
+
);
|
|
369
|
+
} else {
|
|
370
|
+
// TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup
|
|
371
|
+
await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {
|
|
372
|
+
await identity.ready();
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
invariant(identity.deviceCredentialChain);
|
|
376
|
+
|
|
377
|
+
edgeIdentity = await createChainEdgeIdentity(
|
|
378
|
+
identity.signer,
|
|
379
|
+
identity.identityKey,
|
|
380
|
+
identity.deviceKey,
|
|
381
|
+
identity.deviceCredentialChain,
|
|
382
|
+
[], // TODO(dmaretskyi): Service access credentials.
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
edgeIdentity = await createEphemeralEdgeIdentity();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (this._edgeConnection) {
|
|
390
|
+
this._edgeConnection.setIdentity(edgeIdentity);
|
|
391
|
+
}
|
|
392
|
+
this.networkManager.setPeerInfo({
|
|
393
|
+
identityKey: edgeIdentity.identityKey,
|
|
394
|
+
peerKey: edgeIdentity.peerKey,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
341
397
|
}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import chai, { expect } from 'chai';
|
|
6
|
-
import chaiAsPromised from 'chai-as-promised';
|
|
7
5
|
import { rmSync } from 'node:fs';
|
|
6
|
+
import { afterEach, onTestFinished, describe, expect, test } from 'vitest';
|
|
8
7
|
|
|
9
8
|
import { asyncTimeout, latch, Trigger } from '@dxos/async';
|
|
10
9
|
import { Config } from '@dxos/config';
|
|
@@ -14,13 +13,10 @@ import { type PublicKey } from '@dxos/keys';
|
|
|
14
13
|
import { MemorySignalManagerContext } from '@dxos/messaging';
|
|
15
14
|
import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
|
|
16
15
|
import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
17
|
-
import { afterTest, describe, test } from '@dxos/test';
|
|
18
16
|
import { isNode } from '@dxos/util';
|
|
19
17
|
|
|
20
18
|
import { createMockCredential, createServiceHost } from '../testing';
|
|
21
19
|
|
|
22
|
-
chai.use(chaiAsPromised);
|
|
23
|
-
|
|
24
20
|
describe('ClientServicesHost', () => {
|
|
25
21
|
const dataRoot = '/tmp/dxos/client-services/service-host/storage';
|
|
26
22
|
|
|
@@ -38,7 +34,7 @@ describe('ClientServicesHost', () => {
|
|
|
38
34
|
test('queryCredentials', async () => {
|
|
39
35
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
40
36
|
await host.open(new Context());
|
|
41
|
-
|
|
37
|
+
onTestFinished(() => host.close());
|
|
42
38
|
|
|
43
39
|
await host.services.IdentityService!.createIdentity({});
|
|
44
40
|
const { spaceKey } = await host.services.SpacesService!.createSpace();
|
|
@@ -49,7 +45,7 @@ describe('ClientServicesHost', () => {
|
|
|
49
45
|
tick();
|
|
50
46
|
// console.log(credential);
|
|
51
47
|
});
|
|
52
|
-
|
|
48
|
+
onTestFinished(() => stream.close());
|
|
53
49
|
|
|
54
50
|
await done();
|
|
55
51
|
});
|
|
@@ -57,7 +53,7 @@ describe('ClientServicesHost', () => {
|
|
|
57
53
|
test('write and query credentials', async () => {
|
|
58
54
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
59
55
|
await host.open(new Context());
|
|
60
|
-
|
|
56
|
+
onTestFinished(() => host.close());
|
|
61
57
|
|
|
62
58
|
await host.services.IdentityService!.createIdentity({});
|
|
63
59
|
|
|
@@ -86,7 +82,7 @@ describe('ClientServicesHost', () => {
|
|
|
86
82
|
queriedCredential.wake(credential);
|
|
87
83
|
}
|
|
88
84
|
});
|
|
89
|
-
|
|
85
|
+
onTestFinished(() => credentials.close());
|
|
90
86
|
|
|
91
87
|
await queriedCredential.wait();
|
|
92
88
|
});
|
|
@@ -94,7 +90,7 @@ describe('ClientServicesHost', () => {
|
|
|
94
90
|
test('sign presentation', async () => {
|
|
95
91
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
96
92
|
await host.open(new Context());
|
|
97
|
-
|
|
93
|
+
onTestFinished(() => host.close());
|
|
98
94
|
|
|
99
95
|
await host.services.IdentityService!.createIdentity({});
|
|
100
96
|
|
|
@@ -147,9 +143,9 @@ describe('ClientServicesHost', () => {
|
|
|
147
143
|
trigger.wake(identity.identity);
|
|
148
144
|
}
|
|
149
145
|
});
|
|
150
|
-
await expect(asyncTimeout(trigger.wait(), 200)).
|
|
146
|
+
await expect(asyncTimeout(trigger.wait(), 200)).rejects.toBeInstanceOf(Error);
|
|
151
147
|
await stream?.close();
|
|
152
148
|
await host.close();
|
|
153
149
|
}
|
|
154
|
-
})
|
|
150
|
+
});
|
|
155
151
|
});
|
|
@@ -6,7 +6,7 @@ import { Event, synchronized } from '@dxos/async';
|
|
|
6
6
|
import { clientServiceBundle, type ClientServices } from '@dxos/client-protocol';
|
|
7
7
|
import { type Config } from '@dxos/config';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
|
-
import { EdgeClient, type EdgeConnection } from '@dxos/edge-client';
|
|
9
|
+
import { EdgeClient, EdgeHttpClient, createStubEdgeIdentity, type EdgeConnection } from '@dxos/edge-client';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
import { type LevelDB } from '@dxos/kv-store';
|
|
@@ -15,7 +15,7 @@ import { EdgeSignalManager, WebsocketSignalManager, type SignalManager } from '@
|
|
|
15
15
|
import {
|
|
16
16
|
SwarmNetworkManager,
|
|
17
17
|
createIceProvider,
|
|
18
|
-
|
|
18
|
+
createRtcTransportFactory,
|
|
19
19
|
type TransportFactory,
|
|
20
20
|
} from '@dxos/network-manager';
|
|
21
21
|
import { trace } from '@dxos/protocols';
|
|
@@ -29,9 +29,9 @@ import { ServiceRegistry } from './service-registry';
|
|
|
29
29
|
import { DevicesServiceImpl } from '../devices';
|
|
30
30
|
import { DevtoolsHostEvents, DevtoolsServiceImpl } from '../devtools';
|
|
31
31
|
import {
|
|
32
|
-
type CollectDiagnosticsBroadcastHandler,
|
|
33
32
|
createCollectDiagnosticsBroadcastHandler,
|
|
34
33
|
createDiagnostics,
|
|
34
|
+
type CollectDiagnosticsBroadcastHandler,
|
|
35
35
|
} from '../diagnostics';
|
|
36
36
|
import { IdentityServiceImpl, type CreateIdentityOptions } from '../identity';
|
|
37
37
|
import { ContactsServiceImpl } from '../identity/contacts-service';
|
|
@@ -89,6 +89,7 @@ export class ClientServicesHost {
|
|
|
89
89
|
private _callbacks?: ClientServicesHostCallbacks;
|
|
90
90
|
private _devtoolsProxy?: WebsocketRpcClient<{}, ClientServices>;
|
|
91
91
|
private _edgeConnection?: EdgeConnection = undefined;
|
|
92
|
+
private _edgeHttpClient?: EdgeHttpClient = undefined;
|
|
92
93
|
|
|
93
94
|
private _serviceContext!: ServiceContext;
|
|
94
95
|
private readonly _runtimeParams: ServiceContextRuntimeParams;
|
|
@@ -212,13 +213,13 @@ export class ClientServicesHost {
|
|
|
212
213
|
|
|
213
214
|
const edgeEndpoint = config?.get('runtime.services.edge.url');
|
|
214
215
|
if (edgeEndpoint) {
|
|
215
|
-
|
|
216
|
-
this.
|
|
216
|
+
this._edgeConnection = new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: edgeEndpoint });
|
|
217
|
+
this._edgeHttpClient = new EdgeHttpClient(edgeEndpoint);
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
const {
|
|
220
221
|
connectionLog = true,
|
|
221
|
-
transportFactory =
|
|
222
|
+
transportFactory = createRtcTransportFactory(
|
|
222
223
|
{ iceServers: this._config?.get('runtime.services.ice') },
|
|
223
224
|
this._config?.get('runtime.services.iceProviders') &&
|
|
224
225
|
createIceProvider(this._config!.get('runtime.services.iceProviders')!),
|
|
@@ -278,6 +279,7 @@ export class ClientServicesHost {
|
|
|
278
279
|
this._networkManager,
|
|
279
280
|
this._signalManager,
|
|
280
281
|
this._edgeConnection,
|
|
282
|
+
this._edgeHttpClient,
|
|
281
283
|
this._runtimeParams,
|
|
282
284
|
this._config.get('runtime.client.edgeFeatures'),
|
|
283
285
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { expect } from '
|
|
5
|
+
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { type ClientServices } from '@dxos/client-protocol';
|
|
@@ -12,7 +12,6 @@ import { log } from '@dxos/log';
|
|
|
12
12
|
import { schema } from '@dxos/protocols/proto';
|
|
13
13
|
import { type SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
14
14
|
import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
|
|
15
|
-
import { describe, test } from '@dxos/test';
|
|
16
15
|
|
|
17
16
|
import { ServiceRegistry } from './service-registry';
|
|
18
17
|
import { SystemServiceImpl } from '../system';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { expect } from '
|
|
5
|
+
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { asyncTimeout, latch } from '@dxos/async';
|
|
8
8
|
import { createAdmissionCredentials } from '@dxos/credentials';
|
|
@@ -10,7 +10,7 @@ import { AuthStatus } from '@dxos/echo-pipeline';
|
|
|
10
10
|
import { writeMessages } from '@dxos/feed-store';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
13
|
-
import {
|
|
13
|
+
import { openAndClose } from '@dxos/test-utils';
|
|
14
14
|
|
|
15
15
|
import { TestBuilder, type TestPeer } from '../testing';
|
|
16
16
|
|
|
@@ -14,8 +14,11 @@ import {
|
|
|
14
14
|
type DelegateInvitationCredential,
|
|
15
15
|
type MemberInfo,
|
|
16
16
|
} from '@dxos/credentials';
|
|
17
|
-
import { convertLegacyReferences, findInlineObjectOfType, type EchoEdgeReplicator, type EchoHost } from '@dxos/echo-db';
|
|
18
17
|
import {
|
|
18
|
+
convertLegacyReferences,
|
|
19
|
+
findInlineObjectOfType,
|
|
20
|
+
type EchoEdgeReplicator,
|
|
21
|
+
type EchoHost,
|
|
19
22
|
AuthStatus,
|
|
20
23
|
CredentialServerExtension,
|
|
21
24
|
type MeshEchoReplicator,
|
|
@@ -33,7 +36,7 @@ import {
|
|
|
33
36
|
type SpaceDoc,
|
|
34
37
|
} from '@dxos/echo-protocol';
|
|
35
38
|
import { TYPE_PROPERTIES, generateEchoId, getTypeReference } from '@dxos/echo-schema';
|
|
36
|
-
import type { EdgeConnection } from '@dxos/edge-client';
|
|
39
|
+
import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
|
|
37
40
|
import { writeMessages, type FeedStore } from '@dxos/feed-store';
|
|
38
41
|
import { invariant } from '@dxos/invariant';
|
|
39
42
|
import { type Keyring } from '@dxos/keyring';
|
|
@@ -43,7 +46,7 @@ import { AlreadyJoinedError, trace as Trace } from '@dxos/protocols';
|
|
|
43
46
|
import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
44
47
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
45
48
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
46
|
-
import { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
49
|
+
import { type SpaceMetadata, EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
47
50
|
import { SpaceMember, type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
48
51
|
import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
49
52
|
import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
|
|
@@ -107,6 +110,7 @@ export type DataSpaceManagerParams = {
|
|
|
107
110
|
echoHost: EchoHost;
|
|
108
111
|
invitationsManager: InvitationsManager;
|
|
109
112
|
edgeConnection?: EdgeConnection;
|
|
113
|
+
edgeHttpClient?: EdgeHttpClient;
|
|
110
114
|
meshReplicator?: MeshEchoReplicator;
|
|
111
115
|
echoEdgeReplicator?: EchoEdgeReplicator;
|
|
112
116
|
runtimeParams?: DataSpaceManagerRuntimeParams;
|
|
@@ -135,6 +139,7 @@ export class DataSpaceManager extends Resource {
|
|
|
135
139
|
private readonly _echoHost: EchoHost;
|
|
136
140
|
private readonly _invitationsManager: InvitationsManager;
|
|
137
141
|
private readonly _edgeConnection?: EdgeConnection = undefined;
|
|
142
|
+
private readonly _edgeHttpClient?: EdgeHttpClient = undefined;
|
|
138
143
|
private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures = undefined;
|
|
139
144
|
private readonly _meshReplicator?: MeshEchoReplicator = undefined;
|
|
140
145
|
private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
|
|
@@ -154,6 +159,7 @@ export class DataSpaceManager extends Resource {
|
|
|
154
159
|
this._edgeConnection = params.edgeConnection;
|
|
155
160
|
this._edgeFeatures = params.edgeFeatures;
|
|
156
161
|
this._echoEdgeReplicator = params.echoEdgeReplicator;
|
|
162
|
+
this._edgeHttpClient = params.edgeHttpClient;
|
|
157
163
|
this._runtimeParams = params.runtimeParams;
|
|
158
164
|
|
|
159
165
|
trace.diagnostic({
|
|
@@ -388,6 +394,26 @@ export class DataSpaceManager extends Resource {
|
|
|
388
394
|
});
|
|
389
395
|
}
|
|
390
396
|
|
|
397
|
+
async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting) {
|
|
398
|
+
const space = this._spaces.get(spaceKey);
|
|
399
|
+
invariant(space, 'Space not found.');
|
|
400
|
+
|
|
401
|
+
await this._metadataStore.setSpaceEdgeReplicationSetting(spaceKey, setting);
|
|
402
|
+
|
|
403
|
+
if (space.isOpen) {
|
|
404
|
+
switch (setting) {
|
|
405
|
+
case EdgeReplicationSetting.DISABLED:
|
|
406
|
+
await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
|
|
407
|
+
break;
|
|
408
|
+
case EdgeReplicationSetting.ENABLED:
|
|
409
|
+
await this._echoEdgeReplicator?.connectToSpace(space.id);
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
space.stateUpdate.emit();
|
|
415
|
+
}
|
|
416
|
+
|
|
391
417
|
private async _constructSpace(metadata: SpaceMetadata) {
|
|
392
418
|
log('construct space', { metadata });
|
|
393
419
|
const gossip = new Gossip({
|
|
@@ -479,13 +505,22 @@ export class DataSpaceManager extends Resource {
|
|
|
479
505
|
},
|
|
480
506
|
cache: metadata.cache,
|
|
481
507
|
edgeConnection: this._edgeConnection,
|
|
508
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
482
509
|
edgeFeatures: this._edgeFeatures,
|
|
483
510
|
});
|
|
484
511
|
dataSpace.postOpen.append(async () => {
|
|
485
|
-
|
|
512
|
+
const setting = dataSpace.getEdgeReplicationSetting();
|
|
513
|
+
if (setting === EdgeReplicationSetting.ENABLED) {
|
|
514
|
+
await this._echoEdgeReplicator?.connectToSpace(dataSpace.id);
|
|
515
|
+
} else if (this._echoEdgeReplicator) {
|
|
516
|
+
log('not connecting EchoEdgeReplicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
|
|
517
|
+
}
|
|
486
518
|
});
|
|
487
519
|
dataSpace.preClose.append(async () => {
|
|
488
|
-
|
|
520
|
+
const setting = dataSpace.getEdgeReplicationSetting();
|
|
521
|
+
if (setting === EdgeReplicationSetting.ENABLED) {
|
|
522
|
+
await this._echoEdgeReplicator?.disconnectFromSpace(dataSpace.id);
|
|
523
|
+
}
|
|
489
524
|
});
|
|
490
525
|
|
|
491
526
|
presence.newPeer.on((peerState) => {
|
|
@@ -7,10 +7,15 @@ import { AUTH_TIMEOUT } from '@dxos/client-protocol';
|
|
|
7
7
|
import { Context, ContextDisposedError, cancelWithContext } from '@dxos/context';
|
|
8
8
|
import type { SpecificCredential } from '@dxos/credentials';
|
|
9
9
|
import { timed, warnAfterTimeout } from '@dxos/debug';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
type EchoHost,
|
|
12
|
+
type DatabaseRoot,
|
|
13
|
+
createMappedFeedWriter,
|
|
14
|
+
type MetadataStore,
|
|
15
|
+
type Space,
|
|
16
|
+
} from '@dxos/echo-pipeline';
|
|
12
17
|
import { SpaceDocVersion } from '@dxos/echo-protocol';
|
|
13
|
-
import type { EdgeConnection } from '@dxos/edge-client';
|
|
18
|
+
import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
|
|
14
19
|
import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
|
|
15
20
|
import { failedInvariant } from '@dxos/invariant';
|
|
16
21
|
import { type Keyring } from '@dxos/keyring';
|
|
@@ -75,6 +80,7 @@ export type DataSpaceParams = {
|
|
|
75
80
|
callbacks?: DataSpaceCallbacks;
|
|
76
81
|
cache?: SpaceCache;
|
|
77
82
|
edgeConnection?: EdgeConnection;
|
|
83
|
+
edgeHttpClient?: EdgeHttpClient;
|
|
78
84
|
edgeFeatures?: Runtime.Client.EdgeFeatures;
|
|
79
85
|
};
|
|
80
86
|
|
|
@@ -96,7 +102,7 @@ export class DataSpace {
|
|
|
96
102
|
private readonly _feedStore: FeedStore<FeedMessage>;
|
|
97
103
|
private readonly _metadataStore: MetadataStore;
|
|
98
104
|
private readonly _signingContext: SigningContext;
|
|
99
|
-
private readonly _notarizationPlugin
|
|
105
|
+
private readonly _notarizationPlugin: NotarizationPlugin;
|
|
100
106
|
private readonly _callbacks: DataSpaceCallbacks;
|
|
101
107
|
private readonly _cache?: SpaceCache = undefined;
|
|
102
108
|
private readonly _echoHost: EchoHost;
|
|
@@ -136,6 +142,11 @@ export class DataSpace {
|
|
|
136
142
|
this._signingContext = params.signingContext;
|
|
137
143
|
this._callbacks = params.callbacks ?? {};
|
|
138
144
|
this._echoHost = params.echoHost;
|
|
145
|
+
this._notarizationPlugin = new NotarizationPlugin({
|
|
146
|
+
spaceId: this._inner.id,
|
|
147
|
+
edgeClient: params.edgeHttpClient,
|
|
148
|
+
edgeFeatures: params.edgeFeatures,
|
|
149
|
+
});
|
|
139
150
|
|
|
140
151
|
this.authVerifier = new TrustedKeySetAuthVerifier({
|
|
141
152
|
trustedKeysProvider: () =>
|
|
@@ -231,6 +242,7 @@ export class DataSpace {
|
|
|
231
242
|
}
|
|
232
243
|
|
|
233
244
|
await this._inner.open(new Context());
|
|
245
|
+
await this._inner.startProtocol();
|
|
234
246
|
|
|
235
247
|
await this._edgeFeedReplicator?.open();
|
|
236
248
|
|
|
@@ -318,6 +330,7 @@ export class DataSpace {
|
|
|
318
330
|
this._state = SpaceState.SPACE_INITIALIZING;
|
|
319
331
|
log('new state', { state: SpaceState[this._state] });
|
|
320
332
|
|
|
333
|
+
log('initializing control pipeline');
|
|
321
334
|
await this._initializeAndReadControlPipeline();
|
|
322
335
|
|
|
323
336
|
// Allow other tasks to run before loading the data pipeline.
|
|
@@ -325,10 +338,13 @@ export class DataSpace {
|
|
|
325
338
|
|
|
326
339
|
const ready = this.stateUpdate.waitForCondition(() => this._state === SpaceState.SPACE_READY);
|
|
327
340
|
|
|
341
|
+
log('initializing automerge root');
|
|
328
342
|
this._automergeSpaceState.startProcessingRootDocs();
|
|
329
343
|
|
|
330
344
|
// TODO(dmaretskyi): Change so `initializeDataPipeline` doesn't wait for the space to be READY, but rather any state with a valid root.
|
|
345
|
+
log('waiting for space to be ready');
|
|
331
346
|
await ready;
|
|
347
|
+
log('space is ready');
|
|
332
348
|
}
|
|
333
349
|
|
|
334
350
|
private async _enterReadyState() {
|
|
@@ -345,6 +361,7 @@ export class DataSpace {
|
|
|
345
361
|
private async _initializeAndReadControlPipeline() {
|
|
346
362
|
await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
|
|
347
363
|
ctx: this._ctx,
|
|
364
|
+
timeout: 10_000,
|
|
348
365
|
breakOnStall: false,
|
|
349
366
|
});
|
|
350
367
|
|
|
@@ -408,8 +425,16 @@ export class DataSpace {
|
|
|
408
425
|
}
|
|
409
426
|
|
|
410
427
|
if (credentials.length > 0) {
|
|
411
|
-
|
|
412
|
-
|
|
428
|
+
try {
|
|
429
|
+
log('will notarize credentials for feed admission', { count: credentials.length });
|
|
430
|
+
// Never times out
|
|
431
|
+
await this.notarizationPlugin.notarize({ ctx: this._ctx, credentials, timeout: 0 });
|
|
432
|
+
|
|
433
|
+
log('credentials notarized');
|
|
434
|
+
} catch (err) {
|
|
435
|
+
log.error('error notarizing credentials for feed admission', err);
|
|
436
|
+
throw err;
|
|
437
|
+
}
|
|
413
438
|
|
|
414
439
|
// Set this after credentials are notarized so that on failure we will retry.
|
|
415
440
|
await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey!, this.inner.dataFeedKey!);
|
|
@@ -546,6 +571,10 @@ export class DataSpace {
|
|
|
546
571
|
this.stateUpdate.emit();
|
|
547
572
|
}
|
|
548
573
|
|
|
574
|
+
getEdgeReplicationSetting() {
|
|
575
|
+
return this._metadataStore.getSpaceEdgeReplicationSetting(this.key);
|
|
576
|
+
}
|
|
577
|
+
|
|
549
578
|
private _onFeedAdded = async (feed: FeedWrapper<any>) => {
|
|
550
579
|
await this._edgeFeedReplicator!.addFeed(feed);
|
|
551
580
|
};
|