@dxos/client-services 0.1.56-main.bf228a7 → 0.1.56-main.c19b7cd
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-FD4L7N4K.mjs → chunk-ZOTHWLK5.mjs} +623 -335
- package/dist/lib/browser/chunk-ZOTHWLK5.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +23 -19
- 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 +2 -2
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +752 -461
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +1016 -729
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/packlets/identity/identity-manager.d.ts +2 -1
- package/dist/types/src/packlets/identity/identity-manager.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/logging/logging-service.d.ts +6 -2
- package/dist/types/src/packlets/logging/logging-service.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/diagnostics.d.ts +46 -0
- package/dist/types/src/packlets/services/diagnostics.d.ts.map +1 -0
- package/dist/types/src/packlets/services/index.d.ts +1 -0
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts +16 -0
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -0
- 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 +7 -3
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts +6 -0
- package/dist/types/src/packlets/services/util.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +12 -2
- package/dist/types/src/packlets/system/system-service.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/packlets/vault/worker-session.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +2 -0
- package/dist/types/src/version.d.ts.map +1 -0
- package/package.json +34 -33
- package/src/packlets/devices/devices-service.test.ts +2 -1
- package/src/packlets/identity/identity-manager.test.ts +4 -3
- package/src/packlets/identity/identity-manager.ts +9 -5
- package/src/packlets/identity/identity-service.test.ts +2 -1
- 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/logging/logging-service.ts +17 -9
- package/src/packlets/network/network-service.test.ts +2 -1
- package/src/packlets/services/client-rpc-server.ts +4 -4
- package/src/packlets/services/diagnostics.ts +211 -0
- package/src/packlets/services/index.ts +1 -0
- package/src/packlets/services/platform.ts +48 -0
- package/src/packlets/services/service-context.test.ts +59 -0
- package/src/packlets/services/service-context.ts +13 -9
- package/src/packlets/services/service-host.test.ts +11 -10
- package/src/packlets/services/service-host.ts +37 -21
- package/src/packlets/services/service-registry.test.ts +3 -1
- package/src/packlets/services/util.ts +33 -0
- package/src/packlets/spaces/data-space.ts +17 -5
- package/src/packlets/spaces/spaces-service.test.ts +2 -1
- package/src/packlets/system/system-service.test.ts +1 -0
- package/src/packlets/system/system-service.ts +34 -2
- 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/packlets/vault/worker-session.ts +6 -1
- package/src/version.ts +1 -0
- package/dist/lib/browser/chunk-FD4L7N4K.mjs.map +0 -7
|
@@ -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,14 +50,14 @@ 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({});
|
|
56
57
|
|
|
57
58
|
const testCredential = await createMockCredential({
|
|
58
|
-
signer: host.
|
|
59
|
-
issuer: host.
|
|
59
|
+
signer: host.context.keyring,
|
|
60
|
+
issuer: host.context.identityManager.identity!.deviceKey,
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
// Test if Identity exposes haloSpace key.
|
|
@@ -86,14 +87,14 @@ 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({});
|
|
93
94
|
|
|
94
95
|
const testCredential = await createMockCredential({
|
|
95
|
-
signer: host.
|
|
96
|
-
issuer: host.
|
|
96
|
+
signer: host.context.keyring,
|
|
97
|
+
issuer: host.context.identityManager.identity!.deviceKey,
|
|
97
98
|
});
|
|
98
99
|
|
|
99
100
|
const nonce = new Uint8Array([0, 0, 0, 0]);
|
|
@@ -117,11 +118,11 @@ 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
|
|
|
124
|
-
expect(host.
|
|
125
|
+
expect(host.context.storage.size).to.exist;
|
|
125
126
|
|
|
126
127
|
await asyncTimeout(host.reset(), 1000);
|
|
127
128
|
await host.close();
|
|
@@ -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';
|
|
@@ -28,6 +30,7 @@ import { NetworkServiceImpl } from '../network';
|
|
|
28
30
|
import { SpacesServiceImpl } from '../spaces';
|
|
29
31
|
import { createStorageObjects } from '../storage';
|
|
30
32
|
import { SystemServiceImpl } from '../system';
|
|
33
|
+
import { createDiagnostics } from './diagnostics';
|
|
31
34
|
import { ServiceContext } from './service-context';
|
|
32
35
|
import { ServiceRegistry } from './service-registry';
|
|
33
36
|
|
|
@@ -64,11 +67,13 @@ export type InitializeOptions = {
|
|
|
64
67
|
/**
|
|
65
68
|
* Remote service implementation.
|
|
66
69
|
*/
|
|
70
|
+
@Trace.resource()
|
|
67
71
|
export class ClientServicesHost {
|
|
68
72
|
private readonly _resourceLock?: ResourceLock;
|
|
69
73
|
private readonly _serviceRegistry: ServiceRegistry<ClientServices>;
|
|
70
74
|
private readonly _systemService: SystemServiceImpl;
|
|
71
75
|
private readonly _loggingService: LoggingServiceImpl;
|
|
76
|
+
private readonly _tracingService = TRACE_PROCESSOR.createTraceSender();
|
|
72
77
|
|
|
73
78
|
private _config?: Config;
|
|
74
79
|
private readonly _statusUpdate = new Event<void>();
|
|
@@ -78,17 +83,19 @@ export class ClientServicesHost {
|
|
|
78
83
|
private _storage?: Storage;
|
|
79
84
|
private _callbacks?: ClientServicesHostCallbacks;
|
|
80
85
|
|
|
81
|
-
_serviceContext!: ServiceContext;
|
|
86
|
+
private _serviceContext!: ServiceContext;
|
|
87
|
+
|
|
88
|
+
@Trace.info()
|
|
82
89
|
private _opening = false;
|
|
90
|
+
|
|
91
|
+
@Trace.info()
|
|
83
92
|
private _open = false;
|
|
84
93
|
|
|
85
94
|
constructor({
|
|
86
95
|
config,
|
|
87
96
|
modelFactory = createDefaultModelFactory(),
|
|
88
|
-
// TODO(burdon): Create ApolloLink abstraction (see Client).
|
|
89
97
|
transportFactory,
|
|
90
98
|
signalManager,
|
|
91
|
-
connectionLog,
|
|
92
99
|
storage,
|
|
93
100
|
// TODO(wittjosiah): Turn this on by default.
|
|
94
101
|
lockKey,
|
|
@@ -107,7 +114,7 @@ export class ClientServicesHost {
|
|
|
107
114
|
lockKey,
|
|
108
115
|
onAcquire: () => {
|
|
109
116
|
if (!this._opening) {
|
|
110
|
-
void this.open();
|
|
117
|
+
void this.open(new Context());
|
|
111
118
|
}
|
|
112
119
|
},
|
|
113
120
|
onRelease: () => this.close(),
|
|
@@ -116,11 +123,11 @@ export class ClientServicesHost {
|
|
|
116
123
|
|
|
117
124
|
this._systemService = new SystemServiceImpl({
|
|
118
125
|
config: this._config,
|
|
119
|
-
|
|
120
126
|
statusUpdate: this._statusUpdate,
|
|
121
|
-
|
|
122
127
|
getCurrentStatus: () => (this.isOpen ? SystemStatus.ACTIVE : SystemStatus.INACTIVE),
|
|
123
|
-
|
|
128
|
+
getDiagnostics: () => {
|
|
129
|
+
return createDiagnostics(this._serviceRegistry.services, this._serviceContext, this._config!);
|
|
130
|
+
},
|
|
124
131
|
onUpdateStatus: async (status: SystemStatus) => {
|
|
125
132
|
if (!this.isOpen && status === SystemStatus.ACTIVE) {
|
|
126
133
|
await this._resourceLock?.acquire();
|
|
@@ -128,7 +135,6 @@ export class ClientServicesHost {
|
|
|
128
135
|
await this._resourceLock?.release();
|
|
129
136
|
}
|
|
130
137
|
},
|
|
131
|
-
|
|
132
138
|
onReset: async () => {
|
|
133
139
|
await this.reset();
|
|
134
140
|
},
|
|
@@ -136,9 +142,9 @@ export class ClientServicesHost {
|
|
|
136
142
|
|
|
137
143
|
this._loggingService = new LoggingServiceImpl();
|
|
138
144
|
|
|
139
|
-
// TODO(burdon): Start to think of DMG (dynamic services).
|
|
140
145
|
this._serviceRegistry = new ServiceRegistry<ClientServices>(clientServiceBundle, {
|
|
141
146
|
SystemService: this._systemService,
|
|
147
|
+
TracingService: this._tracingService,
|
|
142
148
|
});
|
|
143
149
|
}
|
|
144
150
|
|
|
@@ -146,6 +152,14 @@ export class ClientServicesHost {
|
|
|
146
152
|
return this._open;
|
|
147
153
|
}
|
|
148
154
|
|
|
155
|
+
get config() {
|
|
156
|
+
return this._config;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
get context() {
|
|
160
|
+
return this._serviceContext;
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
get serviceRegistry() {
|
|
150
164
|
return this._serviceRegistry;
|
|
151
165
|
}
|
|
@@ -165,10 +179,10 @@ export class ClientServicesHost {
|
|
|
165
179
|
*/
|
|
166
180
|
initialize({ config, ...options }: InitializeOptions) {
|
|
167
181
|
invariant(!this._open, 'service host is open');
|
|
182
|
+
log.info('initializing...');
|
|
168
183
|
|
|
169
184
|
if (config) {
|
|
170
185
|
invariant(!this._config, 'config already set');
|
|
171
|
-
|
|
172
186
|
this._config = config;
|
|
173
187
|
if (!this._storage) {
|
|
174
188
|
this._storage = createStorageObjects(config.get('runtime.client.storage', {})!).storage;
|
|
@@ -190,16 +204,19 @@ export class ClientServicesHost {
|
|
|
190
204
|
transportFactory,
|
|
191
205
|
signalManager,
|
|
192
206
|
});
|
|
207
|
+
|
|
208
|
+
log.info('initialized');
|
|
193
209
|
}
|
|
194
210
|
|
|
195
211
|
@synchronized
|
|
196
|
-
|
|
212
|
+
@Trace.span()
|
|
213
|
+
async open(ctx: Context) {
|
|
197
214
|
if (this._open) {
|
|
198
215
|
return;
|
|
199
216
|
}
|
|
200
217
|
|
|
201
218
|
const traceId = PublicKey.random().toHex();
|
|
202
|
-
log.trace('dxos.
|
|
219
|
+
log.trace('dxos.client-services.host.open', trace.begin({ id: traceId }));
|
|
203
220
|
|
|
204
221
|
invariant(this._config, 'config not set');
|
|
205
222
|
invariant(this._storage, 'storage not set');
|
|
@@ -207,13 +224,11 @@ export class ClientServicesHost {
|
|
|
207
224
|
invariant(this._networkManager, 'network manager not set');
|
|
208
225
|
|
|
209
226
|
this._opening = true;
|
|
210
|
-
log('opening...', { lockKey: this._resourceLock?.lockKey });
|
|
227
|
+
log.info('opening...', { lockKey: this._resourceLock?.lockKey });
|
|
211
228
|
await this._resourceLock?.acquire();
|
|
212
229
|
|
|
213
230
|
await this._loggingService.open();
|
|
214
231
|
|
|
215
|
-
// TODO(wittjosiah): Make re-entrant.
|
|
216
|
-
// TODO(burdon): Break into components.
|
|
217
232
|
this._serviceContext = new ServiceContext(
|
|
218
233
|
this._storage,
|
|
219
234
|
this._networkManager,
|
|
@@ -221,7 +236,6 @@ export class ClientServicesHost {
|
|
|
221
236
|
this._modelFactory,
|
|
222
237
|
);
|
|
223
238
|
|
|
224
|
-
// TODO(burdon): Start to think of DMG (dynamic services).
|
|
225
239
|
this._serviceRegistry.setServices({
|
|
226
240
|
SystemService: this._systemService,
|
|
227
241
|
|
|
@@ -248,6 +262,7 @@ export class ClientServicesHost {
|
|
|
248
262
|
NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager, this._serviceContext.signalManager),
|
|
249
263
|
|
|
250
264
|
LoggingService: this._loggingService,
|
|
265
|
+
TracingService: this._tracingService,
|
|
251
266
|
|
|
252
267
|
// TODO(burdon): Move to new protobuf definitions.
|
|
253
268
|
DevtoolsHost: new DevtoolsServiceImpl({
|
|
@@ -257,29 +272,30 @@ export class ClientServicesHost {
|
|
|
257
272
|
}),
|
|
258
273
|
});
|
|
259
274
|
|
|
260
|
-
await this._serviceContext.open();
|
|
275
|
+
await this._serviceContext.open(ctx);
|
|
261
276
|
this._opening = false;
|
|
262
277
|
this._open = true;
|
|
263
278
|
this._statusUpdate.emit();
|
|
264
279
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
265
|
-
log('opened', { deviceKey });
|
|
266
|
-
log.trace('dxos.
|
|
280
|
+
log.info('opened', { deviceKey });
|
|
281
|
+
log.trace('dxos.client-services.host.open', trace.end({ id: traceId }));
|
|
267
282
|
}
|
|
268
283
|
|
|
269
284
|
@synchronized
|
|
285
|
+
@Trace.span()
|
|
270
286
|
async close() {
|
|
271
287
|
if (!this._open) {
|
|
272
288
|
return;
|
|
273
289
|
}
|
|
274
290
|
|
|
275
291
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
276
|
-
log('closing...', { deviceKey });
|
|
292
|
+
log.info('closing...', { deviceKey });
|
|
277
293
|
this._serviceRegistry.setServices({ SystemService: this._systemService });
|
|
278
294
|
await this._loggingService.close();
|
|
279
295
|
await this._serviceContext.close();
|
|
280
296
|
this._open = false;
|
|
281
297
|
this._statusUpdate.emit();
|
|
282
|
-
log('closed', { deviceKey });
|
|
298
|
+
log.info('closed', { deviceKey });
|
|
283
299
|
}
|
|
284
300
|
|
|
285
301
|
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,12 +32,13 @@ 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({
|
|
38
39
|
config: new Config({ runtime: { client: { remoteSource } } }),
|
|
39
40
|
getCurrentStatus: () => SystemStatus.ACTIVE,
|
|
41
|
+
getDiagnostics: async () => ({}),
|
|
40
42
|
onReset: () => {},
|
|
41
43
|
onUpdateStatus: () => {},
|
|
42
44
|
statusUpdate: new Event(),
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { PublicKey } from '@dxos/keys';
|
|
6
|
+
import { humanize } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
// TODO(burdon): Move to util.
|
|
9
|
+
|
|
10
|
+
export type JsonStringifyOptions = {
|
|
11
|
+
truncate?: boolean;
|
|
12
|
+
humanize?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const jsonStringify = <T>(data: T, options: JsonStringifyOptions) => {
|
|
16
|
+
if (options.humanize || options.truncate) {
|
|
17
|
+
return JSON.parse(JSON.stringify(data, jsonKeyReplacer(options)));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const jsonKeyReplacer = (options: JsonStringifyOptions) => (key: string, value: any) => {
|
|
24
|
+
if (typeof value === 'string') {
|
|
25
|
+
// Infer if key.
|
|
26
|
+
const key = PublicKey.fromHex(value);
|
|
27
|
+
if (key.toHex() === value) {
|
|
28
|
+
return options.humanize ? humanize(key) : key.truncate();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return value;
|
|
33
|
+
};
|
|
@@ -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,
|
|
@@ -6,18 +6,22 @@ import { Event } from '@dxos/async';
|
|
|
6
6
|
import { Stream } from '@dxos/codec-protobuf';
|
|
7
7
|
import { Config } from '@dxos/config';
|
|
8
8
|
import {
|
|
9
|
+
GetDiagnosticsRequest,
|
|
9
10
|
SystemService,
|
|
10
11
|
SystemStatus,
|
|
11
12
|
UpdateStatusRequest,
|
|
12
13
|
QueryStatusRequest,
|
|
13
14
|
QueryStatusResponse,
|
|
14
15
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
15
|
-
import { MaybePromise } from '@dxos/util';
|
|
16
|
+
import { jsonKeyReplacer, MaybePromise } from '@dxos/util';
|
|
17
|
+
|
|
18
|
+
import { Diagnostics } from '../services';
|
|
16
19
|
|
|
17
20
|
export type SystemServiceOptions = {
|
|
18
21
|
config?: Config;
|
|
19
22
|
statusUpdate: Event<void>;
|
|
20
23
|
getCurrentStatus: () => SystemStatus;
|
|
24
|
+
getDiagnostics: () => Promise<Partial<Diagnostics>>;
|
|
21
25
|
onUpdateStatus: (status: SystemStatus) => MaybePromise<void>;
|
|
22
26
|
onReset: () => MaybePromise<void>;
|
|
23
27
|
};
|
|
@@ -28,11 +32,20 @@ export class SystemServiceImpl implements SystemService {
|
|
|
28
32
|
private readonly _getCurrentStatus: SystemServiceOptions['getCurrentStatus'];
|
|
29
33
|
private readonly _onUpdateStatus: SystemServiceOptions['onUpdateStatus'];
|
|
30
34
|
private readonly _onReset: SystemServiceOptions['onReset'];
|
|
35
|
+
private readonly _getDiagnostics: SystemServiceOptions['getDiagnostics'];
|
|
31
36
|
|
|
32
|
-
constructor({
|
|
37
|
+
constructor({
|
|
38
|
+
config,
|
|
39
|
+
statusUpdate,
|
|
40
|
+
getDiagnostics,
|
|
41
|
+
onUpdateStatus,
|
|
42
|
+
getCurrentStatus,
|
|
43
|
+
onReset,
|
|
44
|
+
}: SystemServiceOptions) {
|
|
33
45
|
this._config = config;
|
|
34
46
|
this._statusUpdate = statusUpdate;
|
|
35
47
|
this._getCurrentStatus = getCurrentStatus;
|
|
48
|
+
this._getDiagnostics = getDiagnostics;
|
|
36
49
|
this._onUpdateStatus = onUpdateStatus;
|
|
37
50
|
this._onReset = onReset;
|
|
38
51
|
}
|
|
@@ -41,6 +54,25 @@ export class SystemServiceImpl implements SystemService {
|
|
|
41
54
|
return this._config?.values ?? {};
|
|
42
55
|
}
|
|
43
56
|
|
|
57
|
+
/**
|
|
58
|
+
* NOTE: Since this is serialized as a JSON object, we allow the option to serialize keys.
|
|
59
|
+
*/
|
|
60
|
+
async getDiagnostics({ keys }: GetDiagnosticsRequest = {}) {
|
|
61
|
+
const diagnostics = await this._getDiagnostics();
|
|
62
|
+
return {
|
|
63
|
+
timestamp: new Date(),
|
|
64
|
+
diagnostics: JSON.parse(
|
|
65
|
+
JSON.stringify(
|
|
66
|
+
diagnostics,
|
|
67
|
+
jsonKeyReplacer({
|
|
68
|
+
truncate: keys === GetDiagnosticsRequest.KEY_OPTION.TRUNCATE,
|
|
69
|
+
humanize: keys === GetDiagnosticsRequest.KEY_OPTION.HUMANIZE,
|
|
70
|
+
}),
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
44
76
|
async updateStatus({ status }: UpdateStatusRequest) {
|
|
45
77
|
await this._onUpdateStatus(status);
|
|
46
78
|
}
|
|
@@ -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) {
|
|
@@ -73,6 +73,7 @@ export class WorkerSession {
|
|
|
73
73
|
port: appPort,
|
|
74
74
|
...middleware,
|
|
75
75
|
});
|
|
76
|
+
|
|
76
77
|
this._shellClientRpc = new ClientRpcServer({
|
|
77
78
|
serviceRegistry: this._serviceHost.serviceRegistry,
|
|
78
79
|
port: shellPort,
|
|
@@ -102,7 +103,7 @@ export class WorkerSession {
|
|
|
102
103
|
},
|
|
103
104
|
},
|
|
104
105
|
port: systemPort,
|
|
105
|
-
timeout:
|
|
106
|
+
timeout: 1_000, // With low timeout heartbeat may fail if the tab's thread is saturated.
|
|
106
107
|
});
|
|
107
108
|
|
|
108
109
|
this.bridgeService = this._iframeRpc.rpc.BridgeService;
|
|
@@ -112,10 +113,14 @@ export class WorkerSession {
|
|
|
112
113
|
log.info('opening...');
|
|
113
114
|
await Promise.all([this._clientRpc.open(), this._iframeRpc.open(), this._maybeOpenShell()]);
|
|
114
115
|
|
|
116
|
+
// Wait until the worker's RPC service has started.
|
|
115
117
|
await this._startTrigger.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
|
|
118
|
+
|
|
119
|
+
// TODO(burdon): Comment required.
|
|
116
120
|
if (this.lockKey) {
|
|
117
121
|
void this._afterLockReleases(this.lockKey, () => this.close());
|
|
118
122
|
}
|
|
123
|
+
|
|
119
124
|
log.info('opened');
|
|
120
125
|
}
|
|
121
126
|
|
package/src/version.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DXOS_VERSION = "0.1.56-main.c19b7cd";
|