@dxos/client-services 0.1.56-main.5ff23aa → 0.1.56-main.6293c6e
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-MM7EFAUT.mjs → chunk-BD23GURE.mjs} +428 -366
- package/dist/lib/browser/chunk-BD23GURE.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +20 -23
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +31 -46
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +443 -384
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +443 -392
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +7 -3
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -2
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +2 -1
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +3 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +34 -33
- package/src/packlets/devices/devices-service.test.ts +2 -1
- package/src/packlets/identity/identity-manager.test.ts +15 -3
- package/src/packlets/identity/identity-manager.ts +27 -6
- package/src/packlets/identity/identity-service.test.ts +17 -2
- package/src/packlets/identity/identity-service.ts +23 -14
- package/src/packlets/identity/identity.test.ts +7 -6
- package/src/packlets/identity/identity.ts +8 -3
- package/src/packlets/invitations/device-invitation-protocol.test.ts +2 -1
- package/src/packlets/network/network-service.test.ts +2 -1
- package/src/packlets/services/client-rpc-server.ts +4 -4
- package/src/packlets/services/service-context.test.ts +59 -0
- package/src/packlets/services/service-context.ts +14 -6
- package/src/packlets/services/service-host.test.ts +6 -5
- package/src/packlets/services/service-host.ts +26 -10
- package/src/packlets/services/service-registry.test.ts +2 -1
- package/src/packlets/spaces/data-space.ts +17 -5
- package/src/packlets/spaces/spaces-service.test.ts +2 -1
- package/src/packlets/testing/test-builder.ts +1 -1
- package/src/packlets/vault/iframe-host-runtime.ts +2 -1
- package/src/packlets/vault/worker-runtime.ts +2 -1
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-MM7EFAUT.mjs.map +0 -7
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { AUTH_TIMEOUT, LOAD_CONTROL_FEEDS_TIMEOUT } from '@dxos/client-protocol';
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import {
|
|
8
9
|
DeviceStateMachine,
|
|
9
10
|
CredentialSigner,
|
|
@@ -21,6 +22,7 @@ import { log } from '@dxos/log';
|
|
|
21
22
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
22
23
|
import { AdmittedFeed, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
23
24
|
import { DeviceAdmissionRequest } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
25
|
+
import { trace } from '@dxos/tracing';
|
|
24
26
|
import { ComplexSet } from '@dxos/util';
|
|
25
27
|
|
|
26
28
|
import { TrustedKeySetAuthVerifier } from './authenticator';
|
|
@@ -35,6 +37,7 @@ export type IdentityParams = {
|
|
|
35
37
|
/**
|
|
36
38
|
* Agent identity manager, which includes the agent's Halo space.
|
|
37
39
|
*/
|
|
40
|
+
@trace.resource()
|
|
38
41
|
export class Identity {
|
|
39
42
|
public readonly space: Space;
|
|
40
43
|
private readonly _signer: Signer;
|
|
@@ -76,13 +79,15 @@ export class Identity {
|
|
|
76
79
|
return this._deviceStateMachine.authorizedDeviceKeys;
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
@trace.span()
|
|
83
|
+
async open(ctx: Context) {
|
|
80
84
|
await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);
|
|
81
85
|
await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);
|
|
82
|
-
await this.space.open();
|
|
86
|
+
await this.space.open(ctx);
|
|
83
87
|
}
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
@trace.span()
|
|
90
|
+
async close(ctx: Context) {
|
|
86
91
|
await this.authVerifier.close();
|
|
87
92
|
await this.space.spaceState.removeCredentialProcessor(this._profileStateMachine);
|
|
88
93
|
await this.space.spaceState.removeCredentialProcessor(this._deviceStateMachine);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { asyncChain } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
10
|
import { describe, test, afterTest } from '@dxos/test';
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ const closeAfterTest = async (peer: ServiceContext) => {
|
|
|
19
20
|
describe('services/device', () => {
|
|
20
21
|
test('creates identity', async () => {
|
|
21
22
|
const peer = createServiceContext();
|
|
22
|
-
await peer.open();
|
|
23
|
+
await peer.open(new Context());
|
|
23
24
|
afterTest(() => peer.close());
|
|
24
25
|
|
|
25
26
|
const identity = await peer.createIdentity();
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { NetworkService, ConnectionState } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
10
|
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ describe('NetworkService', () => {
|
|
|
18
19
|
|
|
19
20
|
beforeEach(async () => {
|
|
20
21
|
serviceContext = createServiceContext();
|
|
21
|
-
await serviceContext.open();
|
|
22
|
+
await serviceContext.open(new Context());
|
|
22
23
|
networkService = new NetworkServiceImpl(serviceContext.networkManager, serviceContext.signalManager);
|
|
23
24
|
});
|
|
24
25
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { ClientServices } from '@dxos/client-protocol';
|
|
6
6
|
import { Any, ServiceHandler, Stream } from '@dxos/codec-protobuf';
|
|
7
7
|
import { raise } from '@dxos/debug';
|
|
8
|
-
import { parseMethodName, RpcPeer, RpcPeerOptions } from '@dxos/rpc';
|
|
8
|
+
import { parseMethodName, RpcPeer, RpcPeerOptions, ServiceBundle } from '@dxos/rpc';
|
|
9
9
|
import { MaybePromise } from '@dxos/util';
|
|
10
10
|
|
|
11
11
|
import { ServiceRegistry } from './service-registry';
|
|
@@ -74,16 +74,16 @@ export class ClientRpcServer {
|
|
|
74
74
|
private _getServiceHandler(serviceName: string) {
|
|
75
75
|
if (!this._handlerCache.has(serviceName)) {
|
|
76
76
|
const [key, descriptor] =
|
|
77
|
-
Object.entries(this._serviceRegistry.descriptors).find(
|
|
77
|
+
Object.entries(this._serviceRegistry.descriptors as ServiceBundle<Record<string, any>>).find(
|
|
78
78
|
([key, descriptor]) => descriptor.name === serviceName,
|
|
79
79
|
) ?? raise(new Error(`Service not available: ${serviceName}`));
|
|
80
80
|
|
|
81
|
-
const service = this._serviceRegistry.services[key as keyof ClientServices];
|
|
81
|
+
const service = this._serviceRegistry.services[key as keyof ClientServices] as any;
|
|
82
82
|
if (!service) {
|
|
83
83
|
throw new Error(`Service not available: ${serviceName}`);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
this._handlerCache.set(serviceName, descriptor.createServer(service
|
|
86
|
+
this._handlerCache.set(serviceName, descriptor.createServer(service));
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
return this._handlerCache.get(serviceName)!;
|
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
|
|
7
|
+
import { DocumentModel, DocumentModelState, MutationBuilder } from '@dxos/document-model';
|
|
8
|
+
import { createModelMutation, encodeModelMutation, genesisMutation } from '@dxos/echo-db';
|
|
9
|
+
import { WriteReceipt } from '@dxos/feed-store';
|
|
10
|
+
import { PublicKey } from '@dxos/keys';
|
|
11
|
+
import { log } from '@dxos/log';
|
|
5
12
|
import { MemorySignalManagerContext } from '@dxos/messaging';
|
|
6
13
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
7
14
|
import { describe, test } from '@dxos/test';
|
|
15
|
+
import { Timeframe } from '@dxos/timeframe';
|
|
16
|
+
import { range } from '@dxos/util';
|
|
8
17
|
|
|
9
18
|
import { createServiceContext, syncItemsLocal } from '../testing';
|
|
10
19
|
import { performInvitation } from '../testing/invitation-utils';
|
|
@@ -16,11 +25,61 @@ describe('services/ServiceContext', () => {
|
|
|
16
25
|
await device1.createIdentity();
|
|
17
26
|
const space1 = await device1.dataSpaceManager!.createSpace();
|
|
18
27
|
|
|
28
|
+
const itemId = PublicKey.random().toHex();
|
|
29
|
+
await space1.dataPipeline.databaseHost!.getWriteStream()?.write({
|
|
30
|
+
batch: genesisMutation(itemId, DocumentModel.meta.type),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
let counter = 0;
|
|
34
|
+
|
|
35
|
+
for (const _ in range(5)) {
|
|
36
|
+
const receipts: WriteReceipt[] = [];
|
|
37
|
+
for (const _ in range(50)) {
|
|
38
|
+
receipts.push(
|
|
39
|
+
await space1.dataPipeline.databaseHost!.getWriteStream()!.write({
|
|
40
|
+
batch: createModelMutation(
|
|
41
|
+
itemId,
|
|
42
|
+
encodeModelMutation(DocumentModel.meta, new MutationBuilder().set('counter', ++counter).build()),
|
|
43
|
+
),
|
|
44
|
+
}),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await space1.dataPipeline.pipelineState!.waitUntilTimeframe(
|
|
49
|
+
Timeframe.merge(...receipts.map((receipt) => new Timeframe([[receipt.feedKey, receipt.seq]]))),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
await space1.createEpoch();
|
|
53
|
+
log.info('epoch', { number: space1.dataPipeline.currentEpoch?.subject.assertion.number });
|
|
54
|
+
}
|
|
55
|
+
|
|
19
56
|
const device2 = createServiceContext({ signalContext: networkContext });
|
|
20
57
|
await Promise.all(performInvitation({ host: device1, guest: device2, options: { kind: Invitation.Kind.DEVICE } }));
|
|
21
58
|
|
|
22
59
|
await device2.dataSpaceManager!.waitUntilSpaceReady(space1!.key);
|
|
23
60
|
const space2 = await device2.dataSpaceManager!.spaces.get(space1.key);
|
|
61
|
+
|
|
62
|
+
log.info('peer 2', {
|
|
63
|
+
currentEpoch: space2!.dataPipeline.currentEpoch?.subject.assertion.number,
|
|
64
|
+
appliedEpoch: space2!.dataPipeline.appliedEpoch?.subject.assertion.number,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await space2?.dataPipeline.onNewEpoch.waitForCondition(
|
|
68
|
+
() =>
|
|
69
|
+
space2!.dataPipeline.appliedEpoch?.subject.assertion.number ===
|
|
70
|
+
space1.dataPipeline.currentEpoch?.subject.assertion.number,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(space2!.dataPipeline.currentEpoch!.subject.assertion.number).to.equal(
|
|
74
|
+
space1.dataPipeline.currentEpoch!.subject.assertion.number,
|
|
75
|
+
);
|
|
76
|
+
expect(space2!.dataPipeline.appliedEpoch!.subject.assertion.number).to.equal(
|
|
77
|
+
space1.dataPipeline.appliedEpoch!.subject.assertion.number,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const item2 = space2!.dataPipeline.itemManager.entities.get(itemId);
|
|
81
|
+
expect((item2!.state as DocumentModelState).data.counter).to.equal(counter);
|
|
82
|
+
|
|
24
83
|
await syncItemsLocal(space1.dataPipeline, space2!.dataPipeline);
|
|
25
84
|
});
|
|
26
85
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Trigger } from '@dxos/async';
|
|
6
|
+
import { Context } from '@dxos/context';
|
|
6
7
|
import { CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';
|
|
7
8
|
import { failUndefined } from '@dxos/debug';
|
|
8
9
|
import {
|
|
@@ -26,6 +27,8 @@ import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
|
26
27
|
import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
27
28
|
import { Storage } from '@dxos/random-access-storage';
|
|
28
29
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
30
|
+
import { trace as Trace } from '@dxos/tracing';
|
|
31
|
+
import { safeInstanceof } from '@dxos/util';
|
|
29
32
|
|
|
30
33
|
import { CreateIdentityOptions, IdentityManager, JoinIdentityParams } from '../identity';
|
|
31
34
|
import {
|
|
@@ -40,6 +43,9 @@ import { DataSpaceManager, SigningContext } from '../spaces';
|
|
|
40
43
|
* Shared backend for all client services.
|
|
41
44
|
*/
|
|
42
45
|
// TODO(burdon): Rename/break-up into smaller components. And/or make members private.
|
|
46
|
+
// TODO(dmaretskyi): Gets duplicated in CJS build between normal and testing bundles.
|
|
47
|
+
@safeInstanceof('dxos.client-services.ServiceContext')
|
|
48
|
+
@Trace.resource()
|
|
43
49
|
export class ServiceContext {
|
|
44
50
|
public readonly initialized = new Trigger();
|
|
45
51
|
public readonly dataServiceSubscriptions = new DataServiceSubscriptions();
|
|
@@ -121,7 +127,8 @@ export class ServiceContext {
|
|
|
121
127
|
);
|
|
122
128
|
}
|
|
123
129
|
|
|
124
|
-
|
|
130
|
+
@Trace.span()
|
|
131
|
+
async open(ctx: Context) {
|
|
125
132
|
await this._checkStorageVersion();
|
|
126
133
|
|
|
127
134
|
log('opening...');
|
|
@@ -129,9 +136,9 @@ export class ServiceContext {
|
|
|
129
136
|
await this.signalManager.open();
|
|
130
137
|
await this.networkManager.open();
|
|
131
138
|
await this.spaceManager.open();
|
|
132
|
-
await this.identityManager.open();
|
|
139
|
+
await this.identityManager.open(ctx);
|
|
133
140
|
if (this.identityManager.identity) {
|
|
134
|
-
await this._initialize();
|
|
141
|
+
await this._initialize(ctx);
|
|
135
142
|
}
|
|
136
143
|
log.trace('dxos.sdk.service-context.open', trace.end({ id: this._instanceId }));
|
|
137
144
|
log('opened');
|
|
@@ -155,7 +162,7 @@ export class ServiceContext {
|
|
|
155
162
|
async createIdentity(params: CreateIdentityOptions = {}) {
|
|
156
163
|
const identity = await this.identityManager.createIdentity(params);
|
|
157
164
|
|
|
158
|
-
await this._initialize();
|
|
165
|
+
await this._initialize(new Context());
|
|
159
166
|
return identity;
|
|
160
167
|
}
|
|
161
168
|
|
|
@@ -168,7 +175,7 @@ export class ServiceContext {
|
|
|
168
175
|
private async _acceptIdentity(params: JoinIdentityParams) {
|
|
169
176
|
const identity = await this.identityManager.acceptIdentity(params);
|
|
170
177
|
|
|
171
|
-
await this._initialize();
|
|
178
|
+
await this._initialize(new Context());
|
|
172
179
|
return identity;
|
|
173
180
|
}
|
|
174
181
|
|
|
@@ -181,7 +188,8 @@ export class ServiceContext {
|
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
// Called when identity is created.
|
|
184
|
-
|
|
191
|
+
@Trace.span()
|
|
192
|
+
private async _initialize(ctx: Context) {
|
|
185
193
|
log('initializing spaces...');
|
|
186
194
|
const identity = this.identityManager.identity ?? failUndefined();
|
|
187
195
|
const signingContext: SigningContext = {
|
|
@@ -8,6 +8,7 @@ import { rmSync } from 'node:fs';
|
|
|
8
8
|
|
|
9
9
|
import { asyncTimeout, latch, Trigger } from '@dxos/async';
|
|
10
10
|
import { Config } from '@dxos/config';
|
|
11
|
+
import { Context } from '@dxos/context';
|
|
11
12
|
import { verifyPresentation } from '@dxos/credentials';
|
|
12
13
|
import { PublicKey } from '@dxos/keys';
|
|
13
14
|
import { MemorySignalManagerContext } from '@dxos/messaging';
|
|
@@ -30,7 +31,7 @@ describe('ClientServicesHost', () => {
|
|
|
30
31
|
|
|
31
32
|
test('queryCredentials', async () => {
|
|
32
33
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
33
|
-
await host.open();
|
|
34
|
+
await host.open(new Context());
|
|
34
35
|
afterTest(() => host.close());
|
|
35
36
|
|
|
36
37
|
await host.services.IdentityService!.createIdentity({});
|
|
@@ -49,7 +50,7 @@ describe('ClientServicesHost', () => {
|
|
|
49
50
|
|
|
50
51
|
test('write and query credentials', async () => {
|
|
51
52
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
52
|
-
await host.open();
|
|
53
|
+
await host.open(new Context());
|
|
53
54
|
afterTest(() => host.close());
|
|
54
55
|
|
|
55
56
|
await host.services.IdentityService!.createIdentity({});
|
|
@@ -86,7 +87,7 @@ describe('ClientServicesHost', () => {
|
|
|
86
87
|
|
|
87
88
|
test('sign presentation', async () => {
|
|
88
89
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
89
|
-
await host.open();
|
|
90
|
+
await host.open(new Context());
|
|
90
91
|
afterTest(() => host.close());
|
|
91
92
|
|
|
92
93
|
await host.services.IdentityService!.createIdentity({});
|
|
@@ -117,7 +118,7 @@ describe('ClientServicesHost', () => {
|
|
|
117
118
|
});
|
|
118
119
|
{
|
|
119
120
|
const host = createServiceHost(config, new MemorySignalManagerContext());
|
|
120
|
-
await host.open();
|
|
121
|
+
await host.open(new Context());
|
|
121
122
|
|
|
122
123
|
await host.services.IdentityService?.createIdentity({});
|
|
123
124
|
|
|
@@ -129,7 +130,7 @@ describe('ClientServicesHost', () => {
|
|
|
129
130
|
|
|
130
131
|
{
|
|
131
132
|
const host = createServiceHost(config, new MemorySignalManagerContext());
|
|
132
|
-
await host.open();
|
|
133
|
+
await host.open(new Context());
|
|
133
134
|
const trigger = new Trigger<Identity>();
|
|
134
135
|
|
|
135
136
|
const stream = host.services.IdentityService?.queryIdentity();
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Event, synchronized } from '@dxos/async';
|
|
6
6
|
import { clientServiceBundle, ClientServices } from '@dxos/client-protocol';
|
|
7
7
|
import { Config } from '@dxos/config';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { DocumentModel } from '@dxos/document-model';
|
|
9
10
|
import { DataServiceImpl } from '@dxos/echo-pipeline';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
@@ -17,6 +18,7 @@ import { trace } from '@dxos/protocols';
|
|
|
17
18
|
import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
18
19
|
import { Storage } from '@dxos/random-access-storage';
|
|
19
20
|
import { TextModel } from '@dxos/text-model';
|
|
21
|
+
import { TRACE_PROCESSOR, trace as Trace } from '@dxos/tracing';
|
|
20
22
|
|
|
21
23
|
import { DevicesServiceImpl } from '../devices';
|
|
22
24
|
import { DevtoolsServiceImpl, DevtoolsHostEvents } from '../devtools';
|
|
@@ -65,11 +67,13 @@ export type InitializeOptions = {
|
|
|
65
67
|
/**
|
|
66
68
|
* Remote service implementation.
|
|
67
69
|
*/
|
|
70
|
+
@Trace.resource()
|
|
68
71
|
export class ClientServicesHost {
|
|
69
72
|
private readonly _resourceLock?: ResourceLock;
|
|
70
73
|
private readonly _serviceRegistry: ServiceRegistry<ClientServices>;
|
|
71
74
|
private readonly _systemService: SystemServiceImpl;
|
|
72
75
|
private readonly _loggingService: LoggingServiceImpl;
|
|
76
|
+
private readonly _tracingService = TRACE_PROCESSOR.createTraceSender();
|
|
73
77
|
|
|
74
78
|
private _config?: Config;
|
|
75
79
|
private readonly _statusUpdate = new Event<void>();
|
|
@@ -80,7 +84,11 @@ export class ClientServicesHost {
|
|
|
80
84
|
private _callbacks?: ClientServicesHostCallbacks;
|
|
81
85
|
|
|
82
86
|
private _serviceContext!: ServiceContext;
|
|
87
|
+
|
|
88
|
+
@Trace.info()
|
|
83
89
|
private _opening = false;
|
|
90
|
+
|
|
91
|
+
@Trace.info()
|
|
84
92
|
private _open = false;
|
|
85
93
|
|
|
86
94
|
constructor({
|
|
@@ -106,7 +114,7 @@ export class ClientServicesHost {
|
|
|
106
114
|
lockKey,
|
|
107
115
|
onAcquire: () => {
|
|
108
116
|
if (!this._opening) {
|
|
109
|
-
void this.open();
|
|
117
|
+
void this.open(new Context());
|
|
110
118
|
}
|
|
111
119
|
},
|
|
112
120
|
onRelease: () => this.close(),
|
|
@@ -136,6 +144,7 @@ export class ClientServicesHost {
|
|
|
136
144
|
|
|
137
145
|
this._serviceRegistry = new ServiceRegistry<ClientServices>(clientServiceBundle, {
|
|
138
146
|
SystemService: this._systemService,
|
|
147
|
+
TracingService: this._tracingService,
|
|
139
148
|
});
|
|
140
149
|
}
|
|
141
150
|
|
|
@@ -170,7 +179,7 @@ export class ClientServicesHost {
|
|
|
170
179
|
*/
|
|
171
180
|
initialize({ config, ...options }: InitializeOptions) {
|
|
172
181
|
invariant(!this._open, 'service host is open');
|
|
173
|
-
log
|
|
182
|
+
log('initializing...');
|
|
174
183
|
|
|
175
184
|
if (config) {
|
|
176
185
|
invariant(!this._config, 'config already set');
|
|
@@ -196,11 +205,12 @@ export class ClientServicesHost {
|
|
|
196
205
|
signalManager,
|
|
197
206
|
});
|
|
198
207
|
|
|
199
|
-
log
|
|
208
|
+
log('initialized');
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
@synchronized
|
|
203
|
-
|
|
212
|
+
@Trace.span()
|
|
213
|
+
async open(ctx: Context) {
|
|
204
214
|
if (this._open) {
|
|
205
215
|
return;
|
|
206
216
|
}
|
|
@@ -214,7 +224,7 @@ export class ClientServicesHost {
|
|
|
214
224
|
invariant(this._networkManager, 'network manager not set');
|
|
215
225
|
|
|
216
226
|
this._opening = true;
|
|
217
|
-
log
|
|
227
|
+
log('opening...', { lockKey: this._resourceLock?.lockKey });
|
|
218
228
|
await this._resourceLock?.acquire();
|
|
219
229
|
|
|
220
230
|
await this._loggingService.open();
|
|
@@ -229,7 +239,11 @@ export class ClientServicesHost {
|
|
|
229
239
|
this._serviceRegistry.setServices({
|
|
230
240
|
SystemService: this._systemService,
|
|
231
241
|
|
|
232
|
-
IdentityService: new IdentityServiceImpl(
|
|
242
|
+
IdentityService: new IdentityServiceImpl(
|
|
243
|
+
(params) => this._serviceContext.createIdentity(params),
|
|
244
|
+
this._serviceContext.identityManager,
|
|
245
|
+
this._serviceContext.keyring,
|
|
246
|
+
),
|
|
233
247
|
|
|
234
248
|
InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) =>
|
|
235
249
|
this._serviceContext.getInvitationHandler(invitation),
|
|
@@ -252,6 +266,7 @@ export class ClientServicesHost {
|
|
|
252
266
|
NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager, this._serviceContext.signalManager),
|
|
253
267
|
|
|
254
268
|
LoggingService: this._loggingService,
|
|
269
|
+
TracingService: this._tracingService,
|
|
255
270
|
|
|
256
271
|
// TODO(burdon): Move to new protobuf definitions.
|
|
257
272
|
DevtoolsHost: new DevtoolsServiceImpl({
|
|
@@ -261,29 +276,30 @@ export class ClientServicesHost {
|
|
|
261
276
|
}),
|
|
262
277
|
});
|
|
263
278
|
|
|
264
|
-
await this._serviceContext.open();
|
|
279
|
+
await this._serviceContext.open(ctx);
|
|
265
280
|
this._opening = false;
|
|
266
281
|
this._open = true;
|
|
267
282
|
this._statusUpdate.emit();
|
|
268
283
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
269
|
-
log
|
|
284
|
+
log('opened', { deviceKey });
|
|
270
285
|
log.trace('dxos.client-services.host.open', trace.end({ id: traceId }));
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
@synchronized
|
|
289
|
+
@Trace.span()
|
|
274
290
|
async close() {
|
|
275
291
|
if (!this._open) {
|
|
276
292
|
return;
|
|
277
293
|
}
|
|
278
294
|
|
|
279
295
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
280
|
-
log
|
|
296
|
+
log('closing...', { deviceKey });
|
|
281
297
|
this._serviceRegistry.setServices({ SystemService: this._systemService });
|
|
282
298
|
await this._loggingService.close();
|
|
283
299
|
await this._serviceContext.close();
|
|
284
300
|
this._open = false;
|
|
285
301
|
this._statusUpdate.emit();
|
|
286
|
-
log
|
|
302
|
+
log('closed', { deviceKey });
|
|
287
303
|
}
|
|
288
304
|
|
|
289
305
|
async reset() {
|
|
@@ -7,6 +7,7 @@ import { expect } from 'chai';
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { ClientServices } from '@dxos/client-protocol';
|
|
9
9
|
import { Config } from '@dxos/config';
|
|
10
|
+
import { Context } from '@dxos/context';
|
|
10
11
|
import { log } from '@dxos/log';
|
|
11
12
|
import { schema } from '@dxos/protocols';
|
|
12
13
|
import { SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -31,7 +32,7 @@ describe('service registry', () => {
|
|
|
31
32
|
test('builds a service registry', async () => {
|
|
32
33
|
const remoteSource = 'https://remote.source';
|
|
33
34
|
const serviceContext = createServiceContext();
|
|
34
|
-
await serviceContext.open();
|
|
35
|
+
await serviceContext.open(new Context());
|
|
35
36
|
|
|
36
37
|
const serviceRegistry = new ServiceRegistry(serviceBundle, {
|
|
37
38
|
SystemService: new SystemServiceImpl({
|
|
@@ -55,6 +55,12 @@ export type DataSpaceParams = {
|
|
|
55
55
|
cache?: SpaceCache;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Delete feed blocks after an epoch is created.
|
|
60
|
+
*/
|
|
61
|
+
// TODO(dmaretskyi): Disabled till better times https://github.com/dxos/dxos/issues/3949.
|
|
62
|
+
const ENABLE_FEED_PURGE = false;
|
|
63
|
+
|
|
58
64
|
@trackLeaks('open', 'close')
|
|
59
65
|
export class DataSpace {
|
|
60
66
|
private _ctx = new Context();
|
|
@@ -145,7 +151,7 @@ export class DataSpace {
|
|
|
145
151
|
private async _open() {
|
|
146
152
|
await this._notarizationPlugin.open();
|
|
147
153
|
await this._inner.spaceState.addCredentialProcessor(this._notarizationPlugin);
|
|
148
|
-
await this._inner.open();
|
|
154
|
+
await this._inner.open(new Context());
|
|
149
155
|
this._state = SpaceState.CONTROL_ONLY;
|
|
150
156
|
this.stateUpdate.emit();
|
|
151
157
|
this.metrics = {};
|
|
@@ -323,10 +329,16 @@ export class DataSpace {
|
|
|
323
329
|
});
|
|
324
330
|
|
|
325
331
|
await this.inner.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
|
|
333
|
+
// Clear feed blocks before epoch.
|
|
334
|
+
if (ENABLE_FEED_PURGE) {
|
|
335
|
+
for (const feed of this.inner.dataPipeline.pipelineState?.feeds ?? []) {
|
|
336
|
+
const indexBeforeEpoch = epoch.timeframe.get(feed.key);
|
|
337
|
+
if (indexBeforeEpoch === undefined) {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
await feed.safeClear(0, indexBeforeEpoch + 1);
|
|
330
342
|
}
|
|
331
343
|
}
|
|
332
344
|
}
|
|
@@ -6,6 +6,7 @@ import chai, { expect } from 'chai';
|
|
|
6
6
|
import chaiAsPromised from 'chai-as-promised';
|
|
7
7
|
|
|
8
8
|
import { Trigger } from '@dxos/async';
|
|
9
|
+
import { Context } from '@dxos/context';
|
|
9
10
|
import { PublicKey } from '@dxos/keys';
|
|
10
11
|
import { Space, SpacesService } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
12
|
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
@@ -22,7 +23,7 @@ describe('SpacesService', () => {
|
|
|
22
23
|
|
|
23
24
|
beforeEach(async () => {
|
|
24
25
|
serviceContext = createServiceContext();
|
|
25
|
-
await serviceContext.open();
|
|
26
|
+
await serviceContext.open(new Context());
|
|
26
27
|
spacesService = new SpacesServiceImpl(
|
|
27
28
|
serviceContext.identityManager,
|
|
28
29
|
serviceContext.spaceManager,
|
|
@@ -60,7 +60,7 @@ export const createPeers = async (numPeers: number) => {
|
|
|
60
60
|
return await Promise.all(
|
|
61
61
|
Array.from(Array(numPeers)).map(async () => {
|
|
62
62
|
const peer = createServiceContext({ signalContext });
|
|
63
|
-
await peer.open();
|
|
63
|
+
await peer.open(new Context());
|
|
64
64
|
return peer;
|
|
65
65
|
}),
|
|
66
66
|
);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Trigger } from '@dxos/async';
|
|
6
6
|
import { PROXY_CONNECTION_TIMEOUT, ShellRuntime } from '@dxos/client-protocol';
|
|
7
7
|
import { Config } from '@dxos/config';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { log, logInfo } from '@dxos/log';
|
|
9
10
|
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
|
|
10
11
|
import { createWebRTCTransportFactory, TransportFactory } from '@dxos/network-manager';
|
|
@@ -108,7 +109,7 @@ export class IFrameHostRuntime {
|
|
|
108
109
|
...middleware,
|
|
109
110
|
});
|
|
110
111
|
|
|
111
|
-
await Promise.all([this._clientServices.open(), this._clientRpc.open(), this._shellRuntime?.open()]);
|
|
112
|
+
await Promise.all([this._clientServices.open(new Context()), this._clientRpc.open(), this._shellRuntime?.open()]);
|
|
112
113
|
this._ready.wake(undefined);
|
|
113
114
|
log('started');
|
|
114
115
|
} catch (err: any) {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Trigger } from '@dxos/async';
|
|
6
6
|
import { Config } from '@dxos/config';
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { log } from '@dxos/log';
|
|
8
9
|
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
|
|
9
10
|
import { WebRTCTransportProxyFactory } from '@dxos/network-manager';
|
|
@@ -57,7 +58,7 @@ export class WorkerRuntime {
|
|
|
57
58
|
transportFactory: this._transportFactory,
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
await this._clientServices.open();
|
|
61
|
+
await this._clientServices.open(new Context());
|
|
61
62
|
this._ready.wake(undefined);
|
|
62
63
|
log('started');
|
|
63
64
|
} catch (err: any) {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DXOS_VERSION = "0.1.56-main.
|
|
1
|
+
export const DXOS_VERSION = "0.1.56-main.6293c6e";
|