@dxos/client-services 0.6.13 → 0.6.14-main.2b6a0f3
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-CRXXOI45.mjs → chunk-BBLK6AUB.mjs} +6301 -5383
- package/dist/lib/browser/chunk-BBLK6AUB.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +320 -45
- package/dist/lib/browser/index.mjs.map +4 -4
- 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-PZ3JJJ3K.cjs → chunk-SJEDBF7U.cjs} +6286 -5378
- package/dist/lib/node/chunk-SJEDBF7U.cjs.map +7 -0
- package/dist/lib/node/index.cjs +369 -94
- package/dist/lib/node/index.cjs.map +4 -4
- 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-A6GS6OOD.mjs +8634 -0
- package/dist/lib/node-esm/chunk-A6GS6OOD.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +691 -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/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 +35 -0
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -0
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +10 -0
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -0
- package/dist/types/src/packlets/agents/index.d.ts +3 -0
- package/dist/types/src/packlets/agents/index.d.ts.map +1 -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 +28 -9
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +18 -0
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/identity-service.d.ts +7 -2
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +12 -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 +14 -9
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +2 -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 +7 -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 +5 -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 +35 -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 +44 -39
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +163 -0
- package/src/packlets/agents/edge-agent-service.ts +42 -0
- package/src/packlets/agents/index.ts +6 -0
- 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 +76 -32
- package/src/packlets/identity/identity-recovery-manager.ts +95 -0
- package/src/packlets/identity/identity-service.test.ts +5 -8
- package/src/packlets/identity/identity-service.ts +11 -5
- package/src/packlets/identity/identity.test.ts +130 -239
- package/src/packlets/identity/identity.ts +60 -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 +185 -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 -93
- 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 +113 -35
- package/src/packlets/services/service-host.test.ts +8 -12
- package/src/packlets/services/service-host.ts +25 -7
- 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 +44 -7
- package/src/packlets/spaces/data-space.ts +37 -6
- package/src/packlets/spaces/edge-feed-replicator.test.ts +252 -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 +196 -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-CRXXOI45.mjs.map +0 -7
- package/dist/lib/node/chunk-PZ3JJJ3K.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,19 +30,21 @@ 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';
|
|
30
36
|
|
|
37
|
+
import { EdgeAgentManager } from '../agents';
|
|
31
38
|
import {
|
|
32
39
|
IdentityManager,
|
|
33
40
|
type CreateIdentityOptions,
|
|
34
|
-
type
|
|
41
|
+
type IdentityManagerParams,
|
|
35
42
|
type JoinIdentityParams,
|
|
36
43
|
} from '../identity';
|
|
44
|
+
import { EdgeIdentityRecoveryManager } from '../identity/identity-recovery-manager';
|
|
37
45
|
import {
|
|
38
46
|
DeviceInvitationProtocol,
|
|
47
|
+
type InvitationConnectionParams,
|
|
39
48
|
InvitationsHandler,
|
|
40
49
|
InvitationsManager,
|
|
41
50
|
SpaceInvitationProtocol,
|
|
@@ -43,9 +52,12 @@ import {
|
|
|
43
52
|
} from '../invitations';
|
|
44
53
|
import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
|
|
45
54
|
|
|
46
|
-
export type ServiceContextRuntimeParams =
|
|
55
|
+
export type ServiceContextRuntimeParams = Pick<
|
|
56
|
+
IdentityManagerParams,
|
|
57
|
+
'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'
|
|
58
|
+
> &
|
|
47
59
|
DataSpaceManagerRuntimeParams & {
|
|
48
|
-
invitationConnectionDefaultParams?:
|
|
60
|
+
invitationConnectionDefaultParams?: InvitationConnectionParams;
|
|
49
61
|
disableP2pReplication?: boolean;
|
|
50
62
|
};
|
|
51
63
|
/**
|
|
@@ -56,6 +68,8 @@ export type ServiceContextRuntimeParams = IdentityManagerRuntimeParams &
|
|
|
56
68
|
@safeInstanceof('dxos.client-services.ServiceContext')
|
|
57
69
|
@Trace.resource()
|
|
58
70
|
export class ServiceContext extends Resource {
|
|
71
|
+
private readonly _edgeIdentityUpdateMutex = new Mutex();
|
|
72
|
+
|
|
59
73
|
public readonly initialized = new Trigger();
|
|
60
74
|
public readonly metadataStore: MetadataStore;
|
|
61
75
|
public readonly blobStore: BlobStore;
|
|
@@ -63,6 +77,7 @@ export class ServiceContext extends Resource {
|
|
|
63
77
|
public readonly keyring: Keyring;
|
|
64
78
|
public readonly spaceManager: SpaceManager;
|
|
65
79
|
public readonly identityManager: IdentityManager;
|
|
80
|
+
public readonly recoveryManager: EdgeIdentityRecoveryManager;
|
|
66
81
|
public readonly invitations: InvitationsHandler;
|
|
67
82
|
public readonly invitationsManager: InvitationsManager;
|
|
68
83
|
public readonly echoHost: EchoHost;
|
|
@@ -71,6 +86,7 @@ export class ServiceContext extends Resource {
|
|
|
71
86
|
|
|
72
87
|
// Initialized after identity is initialized.
|
|
73
88
|
public dataSpaceManager?: DataSpaceManager;
|
|
89
|
+
public edgeAgentManager?: EdgeAgentManager;
|
|
74
90
|
|
|
75
91
|
private readonly _handlerFactories = new Map<
|
|
76
92
|
Invitation.Kind,
|
|
@@ -87,6 +103,7 @@ export class ServiceContext extends Resource {
|
|
|
87
103
|
public readonly networkManager: SwarmNetworkManager,
|
|
88
104
|
public readonly signalManager: SignalManager,
|
|
89
105
|
private readonly _edgeConnection: EdgeConnection | undefined,
|
|
106
|
+
private readonly _edgeHttpClient: EdgeHttpClient | undefined,
|
|
90
107
|
public readonly _runtimeParams?: ServiceContextRuntimeParams,
|
|
91
108
|
private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures,
|
|
92
109
|
) {
|
|
@@ -116,31 +133,22 @@ export class ServiceContext extends Resource {
|
|
|
116
133
|
disableP2pReplication: this._runtimeParams?.disableP2pReplication,
|
|
117
134
|
});
|
|
118
135
|
|
|
119
|
-
this.identityManager = new IdentityManager(
|
|
120
|
-
this.metadataStore,
|
|
136
|
+
this.identityManager = new IdentityManager({
|
|
137
|
+
metadataStore: this.metadataStore,
|
|
138
|
+
keyring: this.keyring,
|
|
139
|
+
feedStore: this.feedStore,
|
|
140
|
+
spaceManager: this.spaceManager,
|
|
141
|
+
devicePresenceOfflineTimeout: this._runtimeParams?.devicePresenceOfflineTimeout,
|
|
142
|
+
devicePresenceAnnounceInterval: this._runtimeParams?.devicePresenceAnnounceInterval,
|
|
143
|
+
edgeConnection: this._edgeConnection,
|
|
144
|
+
edgeFeatures: this._edgeFeatures,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
this.recoveryManager = new EdgeIdentityRecoveryManager(
|
|
121
148
|
this.keyring,
|
|
122
|
-
this.
|
|
123
|
-
this.
|
|
124
|
-
this.
|
|
125
|
-
{
|
|
126
|
-
onIdentityConstruction: (identity) => {
|
|
127
|
-
if (this._edgeConnection) {
|
|
128
|
-
log.info('Setting identity on edge connection', {
|
|
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
|
-
},
|
|
149
|
+
this._edgeHttpClient,
|
|
150
|
+
() => this.identityManager.identity,
|
|
151
|
+
this._acceptIdentity.bind(this),
|
|
144
152
|
);
|
|
145
153
|
|
|
146
154
|
this.echoHost = new EchoHost({ kv: this.level });
|
|
@@ -149,6 +157,7 @@ export class ServiceContext extends Resource {
|
|
|
149
157
|
|
|
150
158
|
this.invitations = new InvitationsHandler(
|
|
151
159
|
this.networkManager, //
|
|
160
|
+
this._edgeHttpClient,
|
|
152
161
|
_runtimeParams?.invitationConnectionDefaultParams,
|
|
153
162
|
);
|
|
154
163
|
this.invitationsManager = new InvitationsManager(
|
|
@@ -185,6 +194,11 @@ export class ServiceContext extends Resource {
|
|
|
185
194
|
|
|
186
195
|
log('opening...');
|
|
187
196
|
log.trace('dxos.sdk.service-context.open', trace.begin({ id: this._instanceId }));
|
|
197
|
+
|
|
198
|
+
await this.identityManager.open(ctx);
|
|
199
|
+
|
|
200
|
+
await this._setNetworkIdentity();
|
|
201
|
+
|
|
188
202
|
await this._edgeConnection?.open();
|
|
189
203
|
await this.signalManager.open();
|
|
190
204
|
await this.networkManager.open();
|
|
@@ -200,9 +214,9 @@ export class ServiceContext extends Resource {
|
|
|
200
214
|
|
|
201
215
|
await this.metadataStore.load();
|
|
202
216
|
await this.spaceManager.open();
|
|
203
|
-
await this.identityManager.open(ctx);
|
|
204
217
|
|
|
205
218
|
if (this.identityManager.identity) {
|
|
219
|
+
await this.identityManager.identity.joinNetwork();
|
|
206
220
|
await this._initialize(ctx);
|
|
207
221
|
}
|
|
208
222
|
|
|
@@ -219,6 +233,7 @@ export class ServiceContext extends Resource {
|
|
|
219
233
|
await this.identityManager.identity.space.spaceState.removeCredentialProcessor(this._deviceSpaceSync);
|
|
220
234
|
}
|
|
221
235
|
await this.dataSpaceManager?.close();
|
|
236
|
+
await this.edgeAgentManager?.close();
|
|
222
237
|
await this.identityManager.close();
|
|
223
238
|
await this.spaceManager.close();
|
|
224
239
|
await this.feedStore.close();
|
|
@@ -234,11 +249,16 @@ export class ServiceContext extends Resource {
|
|
|
234
249
|
|
|
235
250
|
async createIdentity(params: CreateIdentityOptions = {}) {
|
|
236
251
|
const identity = await this.identityManager.createIdentity(params);
|
|
252
|
+
await this._setNetworkIdentity();
|
|
253
|
+
await identity.joinNetwork();
|
|
237
254
|
await this._initialize(new Context());
|
|
238
255
|
return identity;
|
|
239
256
|
}
|
|
240
257
|
|
|
241
258
|
getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol {
|
|
259
|
+
if (this.identityManager.identity == null && invitation.kind === Invitation.Kind.SPACE) {
|
|
260
|
+
throw new Error('Identity must be created before joining a space.');
|
|
261
|
+
}
|
|
242
262
|
const factory = this._handlerFactories.get(invitation.kind);
|
|
243
263
|
invariant(factory, `Unknown invitation kind: ${invitation.kind}`);
|
|
244
264
|
return factory(invitation);
|
|
@@ -255,7 +275,10 @@ export class ServiceContext extends Resource {
|
|
|
255
275
|
}
|
|
256
276
|
|
|
257
277
|
private async _acceptIdentity(params: JoinIdentityParams) {
|
|
258
|
-
const identity = await this.identityManager.
|
|
278
|
+
const { identity, identityRecord } = await this.identityManager.prepareIdentity(params);
|
|
279
|
+
await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential! });
|
|
280
|
+
await identity.joinNetwork();
|
|
281
|
+
await this.identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);
|
|
259
282
|
await this._initialize(new Context());
|
|
260
283
|
return identity;
|
|
261
284
|
}
|
|
@@ -292,6 +315,7 @@ export class ServiceContext extends Resource {
|
|
|
292
315
|
echoHost: this.echoHost,
|
|
293
316
|
invitationsManager: this.invitationsManager,
|
|
294
317
|
edgeConnection: this._edgeConnection,
|
|
318
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
295
319
|
echoEdgeReplicator: this._echoEdgeReplicator,
|
|
296
320
|
meshReplicator: this._meshReplicator,
|
|
297
321
|
runtimeParams: this._runtimeParams as DataSpaceManagerRuntimeParams,
|
|
@@ -299,6 +323,14 @@ export class ServiceContext extends Resource {
|
|
|
299
323
|
});
|
|
300
324
|
await this.dataSpaceManager.open();
|
|
301
325
|
|
|
326
|
+
this.edgeAgentManager = new EdgeAgentManager(
|
|
327
|
+
this._edgeFeatures,
|
|
328
|
+
this._edgeHttpClient,
|
|
329
|
+
this.dataSpaceManager,
|
|
330
|
+
identity,
|
|
331
|
+
);
|
|
332
|
+
await this.edgeAgentManager.open();
|
|
333
|
+
|
|
302
334
|
this._handlerFactories.set(Invitation.Kind.SPACE, (invitation) => {
|
|
303
335
|
invariant(this.dataSpaceManager, 'dataSpaceManager not initialized yet');
|
|
304
336
|
return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
|
|
@@ -338,4 +370,50 @@ export class ServiceContext extends Resource {
|
|
|
338
370
|
|
|
339
371
|
await identity.space.spaceState.addCredentialProcessor(this._deviceSpaceSync);
|
|
340
372
|
}
|
|
373
|
+
|
|
374
|
+
private async _setNetworkIdentity(params?: { deviceCredential: Credential }) {
|
|
375
|
+
using _ = await this._edgeIdentityUpdateMutex.acquire();
|
|
376
|
+
|
|
377
|
+
let edgeIdentity: EdgeIdentity;
|
|
378
|
+
const identity = this.identityManager.identity;
|
|
379
|
+
if (identity) {
|
|
380
|
+
log.info('Setting identity on edge connection', {
|
|
381
|
+
identity: identity.identityKey.toHex(),
|
|
382
|
+
swarms: this.networkManager.topics,
|
|
383
|
+
});
|
|
384
|
+
if (params?.deviceCredential) {
|
|
385
|
+
edgeIdentity = await createChainEdgeIdentity(
|
|
386
|
+
identity.signer,
|
|
387
|
+
identity.identityKey,
|
|
388
|
+
identity.deviceKey,
|
|
389
|
+
{ credential: params.deviceCredential },
|
|
390
|
+
[], // TODO(dmaretskyi): Service access credentials.
|
|
391
|
+
);
|
|
392
|
+
} else {
|
|
393
|
+
// TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup
|
|
394
|
+
await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {
|
|
395
|
+
await identity.ready();
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
invariant(identity.deviceCredentialChain);
|
|
399
|
+
|
|
400
|
+
edgeIdentity = await createChainEdgeIdentity(
|
|
401
|
+
identity.signer,
|
|
402
|
+
identity.identityKey,
|
|
403
|
+
identity.deviceKey,
|
|
404
|
+
identity.deviceCredentialChain,
|
|
405
|
+
[], // TODO(dmaretskyi): Service access credentials.
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
edgeIdentity = await createEphemeralEdgeIdentity();
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
this._edgeConnection?.setIdentity(edgeIdentity);
|
|
413
|
+
this._edgeHttpClient?.setIdentity(edgeIdentity);
|
|
414
|
+
this.networkManager.setPeerInfo({
|
|
415
|
+
identityKey: edgeIdentity.identityKey,
|
|
416
|
+
peerKey: edgeIdentity.peerKey,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
341
419
|
}
|
|
@@ -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';
|
|
@@ -26,12 +26,13 @@ import { WebsocketRpcClient } from '@dxos/websocket-rpc';
|
|
|
26
26
|
|
|
27
27
|
import { ServiceContext, type ServiceContextRuntimeParams } from './service-context';
|
|
28
28
|
import { ServiceRegistry } from './service-registry';
|
|
29
|
+
import { EdgeAgentServiceImpl } from '../agents';
|
|
29
30
|
import { DevicesServiceImpl } from '../devices';
|
|
30
31
|
import { DevtoolsHostEvents, DevtoolsServiceImpl } from '../devtools';
|
|
31
32
|
import {
|
|
32
|
-
type CollectDiagnosticsBroadcastHandler,
|
|
33
33
|
createCollectDiagnosticsBroadcastHandler,
|
|
34
34
|
createDiagnostics,
|
|
35
|
+
type CollectDiagnosticsBroadcastHandler,
|
|
35
36
|
} from '../diagnostics';
|
|
36
37
|
import { IdentityServiceImpl, type CreateIdentityOptions } from '../identity';
|
|
37
38
|
import { ContactsServiceImpl } from '../identity/contacts-service';
|
|
@@ -89,6 +90,7 @@ export class ClientServicesHost {
|
|
|
89
90
|
private _callbacks?: ClientServicesHostCallbacks;
|
|
90
91
|
private _devtoolsProxy?: WebsocketRpcClient<{}, ClientServices>;
|
|
91
92
|
private _edgeConnection?: EdgeConnection = undefined;
|
|
93
|
+
private _edgeHttpClient?: EdgeHttpClient = undefined;
|
|
92
94
|
|
|
93
95
|
private _serviceContext!: ServiceContext;
|
|
94
96
|
private readonly _runtimeParams: ServiceContextRuntimeParams;
|
|
@@ -100,6 +102,9 @@ export class ClientServicesHost {
|
|
|
100
102
|
@Trace.info()
|
|
101
103
|
private _open = false;
|
|
102
104
|
|
|
105
|
+
@Trace.info()
|
|
106
|
+
private _resetting = false;
|
|
107
|
+
|
|
103
108
|
constructor({
|
|
104
109
|
config,
|
|
105
110
|
transportFactory,
|
|
@@ -140,7 +145,7 @@ export class ClientServicesHost {
|
|
|
140
145
|
this._systemService = new SystemServiceImpl({
|
|
141
146
|
config: () => this._config,
|
|
142
147
|
statusUpdate: this._statusUpdate,
|
|
143
|
-
getCurrentStatus: () => (this.isOpen ? SystemStatus.ACTIVE : SystemStatus.INACTIVE),
|
|
148
|
+
getCurrentStatus: () => (this.isOpen && !this._resetting ? SystemStatus.ACTIVE : SystemStatus.INACTIVE),
|
|
144
149
|
getDiagnostics: () => {
|
|
145
150
|
return createDiagnostics(this._serviceRegistry.services, this._serviceContext, this._config!);
|
|
146
151
|
},
|
|
@@ -212,13 +217,13 @@ export class ClientServicesHost {
|
|
|
212
217
|
|
|
213
218
|
const edgeEndpoint = config?.get('runtime.services.edge.url');
|
|
214
219
|
if (edgeEndpoint) {
|
|
215
|
-
|
|
216
|
-
this.
|
|
220
|
+
this._edgeConnection = new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: edgeEndpoint });
|
|
221
|
+
this._edgeHttpClient = new EdgeHttpClient(edgeEndpoint);
|
|
217
222
|
}
|
|
218
223
|
|
|
219
224
|
const {
|
|
220
225
|
connectionLog = true,
|
|
221
|
-
transportFactory =
|
|
226
|
+
transportFactory = createRtcTransportFactory(
|
|
222
227
|
{ iceServers: this._config?.get('runtime.services.ice') },
|
|
223
228
|
this._config?.get('runtime.services.iceProviders') &&
|
|
224
229
|
createIceProvider(this._config!.get('runtime.services.iceProviders')!),
|
|
@@ -278,6 +283,7 @@ export class ClientServicesHost {
|
|
|
278
283
|
this._networkManager,
|
|
279
284
|
this._signalManager,
|
|
280
285
|
this._edgeConnection,
|
|
286
|
+
this._edgeHttpClient,
|
|
281
287
|
this._runtimeParams,
|
|
282
288
|
this._config.get('runtime.client.edgeFeatures'),
|
|
283
289
|
);
|
|
@@ -287,8 +293,14 @@ export class ClientServicesHost {
|
|
|
287
293
|
return this._serviceContext.dataSpaceManager!;
|
|
288
294
|
};
|
|
289
295
|
|
|
296
|
+
const agentManagerProvider = async () => {
|
|
297
|
+
await this._serviceContext.initialized.wait();
|
|
298
|
+
return this._serviceContext.edgeAgentManager!;
|
|
299
|
+
};
|
|
300
|
+
|
|
290
301
|
const identityService = new IdentityServiceImpl(
|
|
291
302
|
this._serviceContext.identityManager,
|
|
303
|
+
this._serviceContext.recoveryManager,
|
|
292
304
|
this._serviceContext.keyring,
|
|
293
305
|
() => this._serviceContext.dataSpaceManager!,
|
|
294
306
|
(params) => this._createIdentity(params),
|
|
@@ -328,6 +340,8 @@ export class ClientServicesHost {
|
|
|
328
340
|
config: this._config,
|
|
329
341
|
context: this._serviceContext,
|
|
330
342
|
}),
|
|
343
|
+
|
|
344
|
+
EdgeAgentService: new EdgeAgentServiceImpl(agentManagerProvider),
|
|
331
345
|
});
|
|
332
346
|
|
|
333
347
|
await this._serviceContext.open(ctx);
|
|
@@ -378,6 +392,10 @@ export class ClientServicesHost {
|
|
|
378
392
|
log.trace('dxos.sdk.client-services-host.reset', trace.begin({ id: traceId }));
|
|
379
393
|
|
|
380
394
|
log.info('resetting...');
|
|
395
|
+
// Emit this status update immediately so app returns to fallback.
|
|
396
|
+
// This state is never cleared because the app reloads.
|
|
397
|
+
this._resetting = true;
|
|
398
|
+
this._statusUpdate.emit();
|
|
381
399
|
await this._serviceContext?.close();
|
|
382
400
|
await this._storage!.reset();
|
|
383
401
|
log.info('reset');
|
|
@@ -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
|
|