@dxos/client-services 0.1.41 → 0.1.45-next.45667d4

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.
Files changed (164) hide show
  1. package/dist/lib/browser/{chunk-T73F4MV4.mjs → chunk-IHSMRQ3L.mjs} +985 -867
  2. package/dist/lib/browser/chunk-IHSMRQ3L.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +7 -3
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/packlets/testing/index.mjs +121 -297
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +4 -4
  7. package/dist/lib/node/index.cjs +589 -469
  8. package/dist/lib/node/index.cjs.map +4 -4
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/packlets/testing/index.cjs +688 -740
  11. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  12. package/dist/types/src/index.d.ts +1 -0
  13. package/dist/types/src/index.d.ts.map +1 -1
  14. package/dist/types/src/packlets/devices/devices-service.d.ts +1 -1
  15. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  16. package/dist/types/src/packlets/devtools/devtools.d.ts +4 -2
  17. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  18. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  19. package/dist/types/src/packlets/devtools/network.d.ts +5 -4
  20. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  21. package/dist/types/src/packlets/identity/authenticator.d.ts +1 -1
  22. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  23. package/dist/types/src/packlets/identity/identity-manager.d.ts +2 -4
  24. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  25. package/dist/types/src/packlets/identity/identity.d.ts +1 -1
  26. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  27. package/dist/types/src/packlets/invitations/invitation-extension.d.ts +2 -3
  28. package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +1 -1
  29. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +1 -3
  30. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  31. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -2
  32. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  33. package/dist/types/src/packlets/network/network-service.d.ts +6 -4
  34. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  35. package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
  36. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  37. package/dist/types/src/packlets/services/index.d.ts +0 -1
  38. package/dist/types/src/packlets/services/index.d.ts.map +1 -1
  39. package/dist/types/src/packlets/services/local-client-services.d.ts +1 -1
  40. package/dist/types/src/packlets/services/local-client-services.d.ts.map +1 -1
  41. package/dist/types/src/packlets/services/service-context.d.ts +4 -2
  42. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  43. package/dist/types/src/packlets/services/service-host.d.ts +16 -9
  44. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  45. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +12 -7
  46. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  47. package/dist/types/src/packlets/spaces/data-space.d.ts +15 -10
  48. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  49. package/dist/types/src/packlets/spaces/genesis.d.ts +5 -0
  50. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -0
  51. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +4 -4
  52. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  53. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -1
  54. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  55. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  56. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  57. package/dist/types/src/packlets/testing/credential-utils.d.ts +1 -1
  58. package/dist/types/src/packlets/testing/index.d.ts +0 -1
  59. package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
  60. package/dist/types/src/packlets/testing/invitation-utils.d.ts +13 -7
  61. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  62. package/dist/types/src/packlets/testing/test-builder.d.ts +35 -32
  63. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  64. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +1 -1
  65. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
  66. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts +5 -2
  67. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -1
  68. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +1 -1
  69. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -1
  70. package/dist/types/src/packlets/vault/worker-runtime.d.ts +1 -1
  71. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  72. package/dist/types/src/packlets/vault/worker-session.d.ts +4 -7
  73. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  74. package/package.json +30 -31
  75. package/src/index.ts +1 -0
  76. package/src/packlets/devices/devices-service.ts +5 -5
  77. package/src/packlets/devtools/devtools.ts +25 -4
  78. package/src/packlets/devtools/feeds.ts +10 -10
  79. package/src/packlets/devtools/keys.ts +6 -6
  80. package/src/packlets/devtools/network.ts +14 -13
  81. package/src/packlets/devtools/spaces.ts +4 -4
  82. package/src/packlets/identity/authenticator.test.ts +1 -1
  83. package/src/packlets/identity/authenticator.ts +2 -2
  84. package/src/packlets/identity/identity-manager.test.ts +17 -13
  85. package/src/packlets/identity/identity-manager.ts +21 -22
  86. package/src/packlets/identity/identity-service.ts +3 -3
  87. package/src/packlets/identity/identity.test.ts +65 -36
  88. package/src/packlets/identity/identity.ts +17 -17
  89. package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
  90. package/src/packlets/invitations/device-invitation-protocol.ts +7 -7
  91. package/src/packlets/invitations/invitation-extension.ts +16 -27
  92. package/src/packlets/invitations/invitations-handler.ts +17 -25
  93. package/src/packlets/invitations/invitations-service.ts +11 -11
  94. package/src/packlets/invitations/space-invitation-protocol.test.ts +9 -9
  95. package/src/packlets/invitations/space-invitation-protocol.ts +11 -12
  96. package/src/packlets/logging/logging-service.ts +8 -3
  97. package/src/packlets/network/network-service.test.ts +8 -8
  98. package/src/packlets/network/network-service.ts +20 -8
  99. package/src/packlets/services/client-rpc-server.ts +5 -5
  100. package/src/packlets/services/index.ts +0 -1
  101. package/src/packlets/services/local-client-services.ts +1 -1
  102. package/src/packlets/services/service-context.test.ts +3 -3
  103. package/src/packlets/services/service-context.ts +26 -24
  104. package/src/packlets/services/service-host.test.ts +6 -6
  105. package/src/packlets/services/service-host.ts +57 -31
  106. package/src/packlets/services/service-registry.test.ts +20 -38
  107. package/src/packlets/spaces/data-space-manager.test.ts +17 -29
  108. package/src/packlets/spaces/data-space-manager.ts +29 -35
  109. package/src/packlets/spaces/data-space.ts +73 -47
  110. package/src/packlets/spaces/genesis.ts +81 -0
  111. package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
  112. package/src/packlets/spaces/notarization-plugin.ts +12 -12
  113. package/src/packlets/spaces/spaces-service.test.ts +2 -2
  114. package/src/packlets/spaces/spaces-service.ts +21 -10
  115. package/src/packlets/storage/storage.ts +3 -3
  116. package/src/packlets/system/system-service.test.ts +1 -1
  117. package/src/packlets/system/system-service.ts +1 -1
  118. package/src/packlets/testing/credential-utils.ts +4 -4
  119. package/src/packlets/testing/index.ts +0 -1
  120. package/src/packlets/testing/invitation-utils.ts +28 -33
  121. package/src/packlets/testing/test-builder.ts +132 -168
  122. package/src/packlets/vault/iframe-host-runtime.ts +8 -11
  123. package/src/packlets/vault/iframe-proxy-runtime.ts +25 -9
  124. package/src/packlets/vault/shell-runtime.ts +4 -4
  125. package/src/packlets/vault/vault-resource-lock.ts +2 -2
  126. package/src/packlets/vault/worker-runtime.ts +7 -9
  127. package/src/packlets/vault/worker-session.ts +24 -45
  128. package/dist/lib/browser/chunk-T73F4MV4.mjs.map +0 -7
  129. package/dist/types/src/packlets/services/utils.d.ts +0 -7
  130. package/dist/types/src/packlets/services/utils.d.ts.map +0 -1
  131. package/dist/types/src/packlets/testing/host-test-builder.d.ts +0 -43
  132. package/dist/types/src/packlets/testing/host-test-builder.d.ts.map +0 -1
  133. package/dist/types/src/packlets/tests/client-services.test.d.ts +0 -2
  134. package/dist/types/src/packlets/tests/client-services.test.d.ts.map +0 -1
  135. package/dist/types/src/packlets/tests/client.test.d.ts +0 -2
  136. package/dist/types/src/packlets/tests/client.test.d.ts.map +0 -1
  137. package/dist/types/src/packlets/tests/halo-credentials.test.d.ts +0 -2
  138. package/dist/types/src/packlets/tests/halo-credentials.test.d.ts.map +0 -1
  139. package/dist/types/src/packlets/tests/halo-persistent.test.d.ts +0 -2
  140. package/dist/types/src/packlets/tests/halo-persistent.test.d.ts.map +0 -1
  141. package/dist/types/src/packlets/tests/halo-profile.test.d.ts +0 -2
  142. package/dist/types/src/packlets/tests/halo-profile.test.d.ts.map +0 -1
  143. package/dist/types/src/packlets/tests/invitations.test.d.ts +0 -2
  144. package/dist/types/src/packlets/tests/invitations.test.d.ts.map +0 -1
  145. package/dist/types/src/packlets/tests/shared-worker.test.d.ts +0 -2
  146. package/dist/types/src/packlets/tests/shared-worker.test.d.ts.map +0 -1
  147. package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts +0 -2
  148. package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts.map +0 -1
  149. package/dist/types/src/packlets/tests/spaces.test.d.ts +0 -2
  150. package/dist/types/src/packlets/tests/spaces.test.d.ts.map +0 -1
  151. package/dist/types/src/packlets/tests/text.test.d.ts +0 -2
  152. package/dist/types/src/packlets/tests/text.test.d.ts.map +0 -1
  153. package/src/packlets/services/utils.ts +0 -53
  154. package/src/packlets/testing/host-test-builder.ts +0 -163
  155. package/src/packlets/tests/client-services.test.ts +0 -222
  156. package/src/packlets/tests/client.test.ts +0 -140
  157. package/src/packlets/tests/halo-credentials.test.ts +0 -94
  158. package/src/packlets/tests/halo-persistent.test.ts +0 -53
  159. package/src/packlets/tests/halo-profile.test.ts +0 -48
  160. package/src/packlets/tests/invitations.test.ts +0 -389
  161. package/src/packlets/tests/shared-worker.test.ts +0 -92
  162. package/src/packlets/tests/spaces-invitations.test.ts +0 -46
  163. package/src/packlets/tests/spaces.test.ts +0 -147
  164. package/src/packlets/tests/text.test.ts +0 -206
@@ -5,12 +5,14 @@
5
5
  import assert from 'node:assert';
6
6
 
7
7
  import { Event } from '@dxos/async';
8
- import { clientServiceBundle, ClientServices, createDefaultModelFactory, PublicKey } from '@dxos/client';
8
+ import { clientServiceBundle, ClientServices, createDefaultModelFactory } from '@dxos/client-protocol';
9
9
  import { Config } from '@dxos/config';
10
10
  import { DataServiceImpl } from '@dxos/echo-pipeline';
11
+ import { PublicKey } from '@dxos/keys';
11
12
  import { log } from '@dxos/log';
13
+ import { SignalManager, WebsocketSignalManager } from '@dxos/messaging';
12
14
  import { ModelFactory } from '@dxos/model-factory';
13
- import { NetworkManager } from '@dxos/network-manager';
15
+ import { createWebRTCTransportFactory, NetworkManager, TransportFactory } from '@dxos/network-manager';
14
16
  import { trace } from '@dxos/protocols';
15
17
  import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
16
18
  import { Storage } from '@dxos/random-access-storage';
@@ -34,14 +36,18 @@ export type ClientServicesHostParams = {
34
36
  */
35
37
  config?: Config;
36
38
  modelFactory?: ModelFactory;
37
- networkManager?: NetworkManager;
39
+ transportFactory?: TransportFactory;
40
+ signalManager?: SignalManager;
41
+ connectionLog?: boolean;
38
42
  storage?: Storage;
39
43
  lockKey?: string;
40
44
  };
41
45
 
42
46
  export type InitializeOptions = {
43
47
  config?: Config;
44
- networkManager?: NetworkManager;
48
+ transportFactory?: TransportFactory;
49
+ signalManager?: SignalManager;
50
+ connectionLog?: boolean;
45
51
  };
46
52
 
47
53
  /**
@@ -56,41 +62,41 @@ export class ClientServicesHost {
56
62
  private _config?: Config;
57
63
  private readonly _statusUpdate = new Event<void>();
58
64
  private readonly _modelFactory: ModelFactory;
65
+ private _signalManager?: SignalManager;
59
66
  private _networkManager?: NetworkManager;
60
67
  private _storage?: Storage;
61
68
 
62
- /**
63
- * @internal
64
- */
65
69
  _serviceContext!: ServiceContext;
66
70
  private _opening = false;
67
71
  private _open = false;
68
72
 
69
- private readonly _instanceId = PublicKey.random().toHex();
70
-
71
73
  constructor({
72
74
  config,
73
75
  modelFactory = createDefaultModelFactory(),
74
76
  // TODO(burdon): Create ApolloLink abstraction (see Client).
75
- networkManager,
77
+ transportFactory,
78
+ signalManager,
79
+ connectionLog,
76
80
  storage,
77
81
  // TODO(wittjosiah): Turn this on by default.
78
- lockKey
82
+ lockKey,
79
83
  }: ClientServicesHostParams = {}) {
80
84
  this._storage = storage;
81
85
  this._modelFactory = modelFactory;
82
86
 
83
87
  if (config) {
84
- this.initialize({ config, networkManager });
88
+ this.initialize({ config, transportFactory, signalManager });
85
89
  }
86
90
 
87
91
  this._resourceLock = lockKey
88
92
  ? new VaultResourceLock({
89
93
  lockKey,
90
94
  onAcquire: () => {
91
- this._opening || this.open();
95
+ if (!this._opening) {
96
+ void this.open();
97
+ }
92
98
  },
93
- onRelease: () => this.close()
99
+ onRelease: () => this.close(),
94
100
  })
95
101
  : undefined;
96
102
 
@@ -111,14 +117,14 @@ export class ClientServicesHost {
111
117
 
112
118
  onReset: async () => {
113
119
  await this.reset();
114
- }
120
+ },
115
121
  });
116
122
 
117
123
  this._loggingService = new LoggingServiceImpl();
118
124
 
119
125
  // TODO(burdon): Start to think of DMG (dynamic services).
120
126
  this._serviceRegistry = new ServiceRegistry<ClientServices>(clientServiceBundle, {
121
- SystemService: this._systemService
127
+ SystemService: this._systemService,
122
128
  });
123
129
  }
124
130
 
@@ -143,7 +149,7 @@ export class ClientServicesHost {
143
149
  * Config can also be provided in the constructor.
144
150
  * Can only be called once.
145
151
  */
146
- initialize({ config, networkManager }: InitializeOptions) {
152
+ initialize({ config, ...options }: InitializeOptions) {
147
153
  assert(!this._open, 'service host is open');
148
154
 
149
155
  if (config) {
@@ -155,21 +161,33 @@ export class ClientServicesHost {
155
161
  }
156
162
  }
157
163
 
158
- if (networkManager) {
159
- assert(!this._networkManager, 'network manager already set');
160
- this._networkManager = networkManager;
161
- }
164
+ const {
165
+ connectionLog = true,
166
+ transportFactory = createWebRTCTransportFactory({
167
+ iceServers: this._config?.get('runtime.services.ice'),
168
+ }),
169
+ signalManager = new WebsocketSignalManager(this._config?.get('runtime.services.signaling') ?? []),
170
+ } = options;
171
+ this._signalManager = signalManager;
172
+
173
+ assert(!this._networkManager, 'network manager already set');
174
+ this._networkManager = new NetworkManager({
175
+ log: connectionLog,
176
+ transportFactory,
177
+ signalManager,
178
+ });
162
179
  }
163
180
 
164
181
  async open() {
165
182
  if (this._open) {
166
183
  return;
167
184
  }
168
-
169
- log.trace('dxos.sdk.client-services-host', trace.begin({ id: this._instanceId }));
185
+ const traceId = PublicKey.random().toHex();
186
+ log.trace('dxos.sdk.client-services-host.open', trace.begin({ id: traceId }));
170
187
 
171
188
  assert(this._config, 'config not set');
172
189
  assert(this._storage, 'storage not set');
190
+ assert(this._signalManager, 'signal manager not set');
173
191
  assert(this._networkManager, 'network manager not set');
174
192
 
175
193
  this._opening = true;
@@ -180,7 +198,12 @@ export class ClientServicesHost {
180
198
 
181
199
  // TODO(wittjosiah): Make re-entrant.
182
200
  // TODO(burdon): Break into components.
183
- this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
201
+ this._serviceContext = new ServiceContext(
202
+ this._storage,
203
+ this._networkManager,
204
+ this._signalManager,
205
+ this._modelFactory,
206
+ );
184
207
 
185
208
  // TODO(burdon): Start to think of DMG (dynamic services).
186
209
  this._serviceRegistry.setServices({
@@ -189,7 +212,7 @@ export class ClientServicesHost {
189
212
  IdentityService: new IdentityServiceImpl(this._serviceContext),
190
213
 
191
214
  InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) =>
192
- this._serviceContext.getInvitationHandler(invitation)
215
+ this._serviceContext.getInvitationHandler(invitation),
193
216
  ),
194
217
 
195
218
  DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
@@ -201,12 +224,12 @@ export class ClientServicesHost {
201
224
  async () => {
202
225
  await this._serviceContext.initialized.wait();
203
226
  return this._serviceContext.dataSpaceManager!;
204
- }
227
+ },
205
228
  ),
206
229
 
207
230
  DataService: new DataServiceImpl(this._serviceContext.dataServiceSubscriptions),
208
231
 
209
- NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager),
232
+ NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager, this._serviceContext.signalManager),
210
233
 
211
234
  LoggingService: this._loggingService,
212
235
 
@@ -214,8 +237,8 @@ export class ClientServicesHost {
214
237
  DevtoolsHost: new DevtoolsServiceImpl({
215
238
  events: new DevtoolsHostEvents(),
216
239
  config: this._config,
217
- context: this._serviceContext
218
- })
240
+ context: this._serviceContext,
241
+ }),
219
242
  });
220
243
 
221
244
  await this._serviceContext.open();
@@ -224,6 +247,7 @@ export class ClientServicesHost {
224
247
  this._statusUpdate.emit();
225
248
  const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
226
249
  log('opened', { deviceKey });
250
+ log.trace('dxos.sdk.client-services-host.open', trace.end({ id: traceId }));
227
251
  }
228
252
 
229
253
  async close() {
@@ -239,14 +263,16 @@ export class ClientServicesHost {
239
263
  this._open = false;
240
264
  this._statusUpdate.emit();
241
265
  log('closed', { deviceKey });
242
-
243
- log.trace('dxos.sdk.client-services-host', trace.end({ id: this._instanceId }));
244
266
  }
245
267
 
246
268
  async reset() {
269
+ const traceId = PublicKey.random().toHex();
270
+ log.trace('dxos.sdk.client-services-host.reset', trace.begin({ id: traceId }));
271
+
247
272
  log('resetting...');
248
273
  await this._serviceContext?.close();
249
274
  await this._storage!.reset();
250
275
  log('reset');
276
+ log.trace('dxos.sdk.client-services-host.reset', trace.end({ id: traceId }));
251
277
  }
252
278
  }
@@ -2,43 +2,45 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'node:assert';
5
+ import { expect } from 'chai';
6
6
 
7
- import { Trigger } from '@dxos/async';
8
- import { ClientServices, InvitationsProxy } from '@dxos/client';
7
+ import { Event } from '@dxos/async';
8
+ import { ClientServices } from '@dxos/client-protocol';
9
+ import { Config } from '@dxos/config';
9
10
  import { log } from '@dxos/log';
10
11
  import { schema } from '@dxos/protocols';
11
- import { Invitation, InvitationsService } from '@dxos/protocols/proto/dxos/client/services';
12
+ import { SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
12
13
  import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
13
14
  import { describe, test } from '@dxos/test';
14
15
 
15
- import { InvitationsServiceImpl } from '../invitations';
16
+ import { SystemServiceImpl } from '../system';
16
17
  import { createServiceContext } from '../testing';
17
18
  import { ServiceRegistry } from './service-registry';
18
19
 
19
20
  // TODO(burdon): Create TestService (that doesn't require peers).
20
21
 
21
22
  type TestServices = {
22
- InvitationsService: InvitationsService;
23
+ SystemService: SystemService;
23
24
  };
24
25
 
25
26
  const serviceBundle = createServiceBundle<TestServices>({
26
- InvitationsService: schema.getService('dxos.client.services.InvitationsService')
27
+ SystemService: schema.getService('dxos.client.services.SystemService'),
27
28
  });
28
29
 
29
30
  describe('service registry', () => {
30
31
  test('builds a service registry', async () => {
32
+ const remoteSource = 'https://remote.source';
31
33
  const serviceContext = createServiceContext();
32
34
  await serviceContext.open();
33
- await serviceContext.createIdentity();
34
-
35
- assert(serviceContext.dataSpaceManager);
36
- const space = await serviceContext.dataSpaceManager.createSpace();
37
35
 
38
36
  const serviceRegistry = new ServiceRegistry(serviceBundle, {
39
- InvitationsService: new InvitationsServiceImpl(serviceContext.invitations, (invitation) =>
40
- serviceContext.getInvitationHandler(invitation)
41
- )
37
+ SystemService: new SystemServiceImpl({
38
+ config: new Config({ runtime: { client: { remoteSource } } }),
39
+ getCurrentStatus: () => SystemStatus.ACTIVE,
40
+ onReset: () => {},
41
+ onUpdateStatus: () => {},
42
+ statusUpdate: new Event(),
43
+ }),
42
44
  });
43
45
 
44
46
  const [proxyPort, serverPort] = createLinkedPorts();
@@ -47,44 +49,24 @@ describe('service registry', () => {
47
49
  requested: serviceRegistry.descriptors,
48
50
  exposed: {},
49
51
  handlers: {},
50
- port: proxyPort
52
+ port: proxyPort,
51
53
  });
52
54
 
53
55
  const server = createProtoRpcPeer({
54
56
  exposed: serviceRegistry.descriptors,
55
57
  handlers: serviceRegistry.services as ClientServices,
56
- port: serverPort
58
+ port: serverPort,
57
59
  });
58
60
 
59
61
  log('opening...');
60
62
  await Promise.all([proxy.open(), server.open()]);
61
63
  log('open');
62
64
 
63
- const done = new Trigger(); // createRpcServer
64
-
65
65
  {
66
- const spaceInvitationsProxy = new InvitationsProxy(proxy.rpc.InvitationsService, () => ({
67
- kind: Invitation.Kind.SPACE,
68
- spaceKey: space.key
69
- }));
70
- const observer = spaceInvitationsProxy.createInvitation();
71
- observer.subscribe((invitation: Invitation) => {
72
- switch (invitation.state) {
73
- case Invitation.State.CONNECTING: {
74
- log('connecting', invitation);
75
- void observer.cancel();
76
- break;
77
- }
78
-
79
- case Invitation.State.CANCELLED: {
80
- done.wake();
81
- }
82
- }
83
- });
66
+ const config = await proxy.rpc.SystemService.getConfig();
67
+ expect(config.runtime?.client?.remoteSource).to.equal(remoteSource);
84
68
  }
85
69
 
86
- await done.wait();
87
-
88
70
  // TODO(burdon): Error handling (create tests).
89
71
  // Uncaught Error: Request was terminated because the RPC endpoint is closed.
90
72
  // log('closing...');
@@ -6,19 +6,17 @@ import { expect } from 'chai';
6
6
 
7
7
  import { latch } from '@dxos/async';
8
8
  import { createAdmissionCredentials } from '@dxos/credentials';
9
- import { DocumentModel } from '@dxos/document-model';
10
9
  import { AuthStatus, DataServiceSubscriptions } from '@dxos/echo-pipeline';
11
10
  import { writeMessages } from '@dxos/feed-store';
12
11
  import { log } from '@dxos/log';
13
- import { ModelFactory } from '@dxos/model-factory';
14
- import { test, describe, afterTest } from '@dxos/test';
12
+ import { afterTest, describe, test } from '@dxos/test';
15
13
 
16
- import { createSigningContext, HostTestBuilder, syncItemsLocal } from '../testing';
14
+ import { createSigningContext, TestBuilder, syncItemsLocal } from '../testing';
17
15
  import { DataSpaceManager } from './data-space-manager';
18
16
 
19
17
  describe('DataSpaceManager', () => {
20
18
  test('create space', async () => {
21
- const builder = new HostTestBuilder();
19
+ const builder = new TestBuilder();
22
20
 
23
21
  const peer = builder.createPeer();
24
22
  const identity = await createSigningContext(peer.keyring);
@@ -28,9 +26,7 @@ describe('DataSpaceManager', () => {
28
26
  new DataServiceSubscriptions(),
29
27
  peer.keyring,
30
28
  identity,
31
- new ModelFactory().registerModel(DocumentModel),
32
29
  peer.feedStore,
33
- peer.snapshotStore
34
30
  );
35
31
  await dataSpaceManager.open();
36
32
  afterTest(() => dataSpaceManager.close());
@@ -46,7 +42,7 @@ describe('DataSpaceManager', () => {
46
42
  });
47
43
 
48
44
  test('sync between peers', async () => {
49
- const builder = new HostTestBuilder();
45
+ const builder = new TestBuilder();
50
46
 
51
47
  const peer1 = builder.createPeer();
52
48
  const identity1 = await createSigningContext(peer1.keyring);
@@ -56,9 +52,7 @@ describe('DataSpaceManager', () => {
56
52
  new DataServiceSubscriptions(),
57
53
  peer1.keyring,
58
54
  identity1,
59
- new ModelFactory().registerModel(DocumentModel),
60
55
  peer1.feedStore,
61
- peer1.snapshotStore
62
56
  );
63
57
  await dataSpaceManager1.open();
64
58
  afterTest(() => dataSpaceManager1.close());
@@ -71,9 +65,7 @@ describe('DataSpaceManager', () => {
71
65
  new DataServiceSubscriptions(),
72
66
  peer2.keyring,
73
67
  identity2,
74
- new ModelFactory().registerModel(DocumentModel),
75
68
  peer2.feedStore,
76
- peer1.snapshotStore
77
69
  );
78
70
  await dataSpaceManager2.open();
79
71
  afterTest(() => dataSpaceManager2.close());
@@ -88,14 +80,14 @@ describe('DataSpaceManager', () => {
88
80
  identity1.credentialSigner,
89
81
  identity2.identityKey,
90
82
  space1.key,
91
- space1.inner.genesisFeedKey
92
- )
83
+ space1.inner.genesisFeedKey,
84
+ ),
93
85
  );
94
86
 
95
87
  // Accept must be called after admission so that the peer can authenticate for notarization.
96
88
  const space2 = await dataSpaceManager2.acceptSpace({
97
89
  spaceKey: space1.key,
98
- genesisFeedKey: space1.inner.genesisFeedKey
90
+ genesisFeedKey: space1.inner.genesisFeedKey,
99
91
  });
100
92
  await dataSpaceManager2.waitUntilSpaceReady(space2.key);
101
93
 
@@ -104,14 +96,14 @@ describe('DataSpaceManager', () => {
104
96
  identity: identity1.identityKey,
105
97
  device: identity1.deviceKey,
106
98
  control: space1.inner.controlFeedKey,
107
- data: space1.inner.dataFeedKey
99
+ data: space1.inner.dataFeedKey,
108
100
  },
109
101
  peer2: {
110
102
  identity: identity2.identityKey,
111
103
  device: identity2.deviceKey,
112
104
  control: space2.inner.controlFeedKey,
113
- data: space2.inner.dataFeedKey
114
- }
105
+ data: space2.inner.dataFeedKey,
106
+ },
115
107
  });
116
108
 
117
109
  await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
@@ -120,12 +112,12 @@ describe('DataSpaceManager', () => {
120
112
  log('', {
121
113
  space1: {
122
114
  timeframe: space1.inner.controlPipeline.state.timeframe,
123
- endTimeframe: space1.inner.controlPipeline.state.endTimeframe
115
+ endTimeframe: space1.inner.controlPipeline.state.endTimeframe,
124
116
  },
125
117
  space2: {
126
118
  timeframe: space2.inner.controlPipeline.state.timeframe,
127
- endTimeframe: space2.inner.controlPipeline.state.endTimeframe
128
- }
119
+ endTimeframe: space2.inner.controlPipeline.state.endTimeframe,
120
+ },
129
121
  });
130
122
  log.break();
131
123
 
@@ -138,7 +130,7 @@ describe('DataSpaceManager', () => {
138
130
  });
139
131
 
140
132
  test('pub/sub API', async () => {
141
- const builder = new HostTestBuilder();
133
+ const builder = new TestBuilder();
142
134
 
143
135
  const peer1 = builder.createPeer();
144
136
  const identity1 = await createSigningContext(peer1.keyring);
@@ -148,9 +140,7 @@ describe('DataSpaceManager', () => {
148
140
  new DataServiceSubscriptions(),
149
141
  peer1.keyring,
150
142
  identity1,
151
- new ModelFactory().registerModel(DocumentModel),
152
143
  peer1.feedStore,
153
- peer1.snapshotStore
154
144
  );
155
145
  await dataSpaceManager1.open();
156
146
  afterTest(() => dataSpaceManager1.close());
@@ -163,9 +153,7 @@ describe('DataSpaceManager', () => {
163
153
  new DataServiceSubscriptions(),
164
154
  peer2.keyring,
165
155
  identity2,
166
- new ModelFactory().registerModel(DocumentModel),
167
156
  peer2.feedStore,
168
- peer1.snapshotStore
169
157
  );
170
158
  await dataSpaceManager2.open();
171
159
  afterTest(() => dataSpaceManager2.close());
@@ -180,14 +168,14 @@ describe('DataSpaceManager', () => {
180
168
  identity1.credentialSigner,
181
169
  identity2.identityKey,
182
170
  space1.key,
183
- space1.inner.genesisFeedKey
184
- )
171
+ space1.inner.genesisFeedKey,
172
+ ),
185
173
  );
186
174
 
187
175
  // Accept must be called after admission so that the peer can authenticate for notarization.
188
176
  const space2 = await dataSpaceManager2.acceptSpace({
189
177
  spaceKey: space1.key,
190
- genesisFeedKey: space1.inner.genesisFeedKey
178
+ genesisFeedKey: space1.inner.genesisFeedKey,
191
179
  });
192
180
 
193
181
  // Coincidentally, this also waits until a P2P connection is established between peers.
@@ -5,33 +5,33 @@
5
5
  import assert from 'node:assert';
6
6
 
7
7
  import { Event, synchronized, trackLeaks } from '@dxos/async';
8
- import { SpaceState } from '@dxos/client';
9
8
  import { cancelWithContext, Context } from '@dxos/context';
10
- import { getCredentialAssertion } from '@dxos/credentials';
11
- import {
12
- DataServiceSubscriptions,
13
- MetadataStore,
14
- SigningContext,
15
- SnapshotManager,
16
- SnapshotStore,
17
- Space,
18
- spaceGenesis,
19
- SpaceManager
20
- } from '@dxos/echo-pipeline';
9
+ import { CredentialSigner, getCredentialAssertion } from '@dxos/credentials';
10
+ import { DataServiceSubscriptions, MetadataStore, Space, SpaceManager } from '@dxos/echo-pipeline';
21
11
  import { FeedStore } from '@dxos/feed-store';
22
12
  import { Keyring } from '@dxos/keyring';
23
13
  import { PublicKey } from '@dxos/keys';
24
14
  import { log } from '@dxos/log';
25
- import { ModelFactory } from '@dxos/model-factory';
26
15
  import { trace } from '@dxos/protocols';
16
+ import { SpaceState } from '@dxos/protocols/proto/dxos/client/services';
27
17
  import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
28
18
  import { SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
19
+ import { Credential, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
29
20
  import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
30
21
  import { Timeframe } from '@dxos/timeframe';
31
22
  import { ComplexMap, deferFunction } from '@dxos/util';
32
23
 
33
24
  import { createAuthProvider } from '../identity';
34
25
  import { DataSpace } from './data-space';
26
+ import { spaceGenesis } from './genesis';
27
+
28
+ export interface SigningContext {
29
+ identityKey: PublicKey;
30
+ deviceKey: PublicKey;
31
+ credentialSigner: CredentialSigner; // TODO(burdon): Already has keyring.
32
+ recordCredential: (credential: Credential) => Promise<void>;
33
+ profile?: ProfileDocument;
34
+ }
35
35
 
36
36
  export type AcceptSpaceOptions = {
37
37
  spaceKey: PublicKey;
@@ -60,7 +60,6 @@ export class DataSpaceManager {
60
60
 
61
61
  private _isOpen = false;
62
62
  private readonly _instanceId = PublicKey.random().toHex();
63
- public _traceParent?: string;
64
63
 
65
64
  constructor(
66
65
  private readonly _spaceManager: SpaceManager,
@@ -68,9 +67,7 @@ export class DataSpaceManager {
68
67
  private readonly _dataServiceSubscriptions: DataServiceSubscriptions,
69
68
  private readonly _keyring: Keyring,
70
69
  private readonly _signingContext: SigningContext,
71
- private readonly _modelFactory: ModelFactory,
72
70
  private readonly _feedStore: FeedStore<FeedMessage>,
73
- private readonly _snapshotStore: SnapshotStore
74
71
  ) {}
75
72
 
76
73
  // TODO(burdon): Remove.
@@ -81,7 +78,7 @@ export class DataSpaceManager {
81
78
  @synchronized
82
79
  async open() {
83
80
  log('open');
84
- log.trace('dxos.echo.data-space-manager', trace.begin({ id: this._instanceId, parentId: this._traceParent }));
81
+ log.trace('dxos.echo.data-space-manager.open', trace.begin({ id: this._instanceId }));
85
82
  await this._metadataStore.load();
86
83
  log('metadata loaded', { spaces: this._metadataStore.spaces.length });
87
84
 
@@ -97,6 +94,7 @@ export class DataSpaceManager {
97
94
 
98
95
  this._isOpen = true;
99
96
  this.updated.emit();
97
+ log.trace('dxos.echo.data-space-manager.open', trace.end({ id: this._instanceId }));
100
98
  }
101
99
 
102
100
  @synchronized
@@ -107,7 +105,6 @@ export class DataSpaceManager {
107
105
  for (const space of this._spaces.values()) {
108
106
  await space.close();
109
107
  }
110
- log.trace('dxos.echo.data-space-manager', trace.end({ id: this._instanceId }));
111
108
  }
112
109
 
113
110
  /**
@@ -123,7 +120,7 @@ export class DataSpaceManager {
123
120
  key: spaceKey,
124
121
  genesisFeedKey: controlFeedKey,
125
122
  controlFeedKey,
126
- dataFeedKey
123
+ dataFeedKey,
127
124
  };
128
125
 
129
126
  log('creating space...', { spaceKey });
@@ -153,7 +150,7 @@ export class DataSpaceManager {
153
150
  key: opts.spaceKey,
154
151
  genesisFeedKey: opts.genesisFeedKey,
155
152
  controlTimeframe: opts.controlTimeframe,
156
- dataTimeframe: opts.dataTimeframe
153
+ dataTimeframe: opts.dataTimeframe,
157
154
  };
158
155
 
159
156
  const space = await this._constructSpace(metadata);
@@ -176,22 +173,21 @@ export class DataSpaceManager {
176
173
  this.updated.waitForCondition(() => {
177
174
  const space = this._spaces.get(spaceKey);
178
175
  return !!space && space.state === SpaceState.READY;
179
- })
176
+ }),
180
177
  );
181
178
  }
182
179
 
183
180
  private async _constructSpace(metadata: SpaceMetadata) {
184
181
  log('construct space', { metadata });
185
182
  const gossip = new Gossip({
186
- localPeerId: this._signingContext.deviceKey
183
+ localPeerId: this._signingContext.deviceKey,
187
184
  });
188
185
  const presence = new Presence({
189
186
  announceInterval: 500,
190
187
  offlineTimeout: 5_000, // TODO(burdon): Config.
191
188
  identityKey: this._signingContext.identityKey,
192
- gossip
189
+ gossip,
193
190
  });
194
- const snapshotManager = new SnapshotManager(this._snapshotStore);
195
191
 
196
192
  const controlFeed =
197
193
  metadata.controlFeedKey && (await this._feedStore.openFeed(metadata.controlFeedKey, { writable: true }));
@@ -202,38 +198,35 @@ export class DataSpaceManager {
202
198
  swarmIdentity: {
203
199
  peerKey: this._signingContext.deviceKey,
204
200
  credentialProvider: createAuthProvider(this._signingContext.credentialSigner),
205
- credentialAuthenticator: deferFunction(() => dataSpace.authVerifier.verifier)
201
+ credentialAuthenticator: deferFunction(() => dataSpace.authVerifier.verifier),
206
202
  },
207
203
  onNetworkConnection: (session) => {
208
204
  session.addExtension(
209
205
  'dxos.mesh.teleport.gossip',
210
- gossip.createExtension({ remotePeerId: session.remotePeerId })
206
+ gossip.createExtension({ remotePeerId: session.remotePeerId }),
211
207
  );
212
- session.addExtension('dxos.mesh.teleport.objectsync', snapshotManager.objectSync.createExtension());
208
+ session.addExtension('dxos.mesh.teleport.objectsync', space.snapshotManager.objectSync.createExtension());
213
209
  session.addExtension('dxos.mesh.teleport.notarization', dataSpace.notarizationPlugin.createExtension());
214
- }
210
+ },
211
+ memberKey: this._signingContext.identityKey,
215
212
  });
216
213
  controlFeed && space.setControlFeed(controlFeed);
217
214
  dataFeed && space.setDataFeed(dataFeed);
218
215
 
219
216
  const dataSpace = new DataSpace({
220
217
  inner: space,
221
- modelFactory: this._modelFactory,
222
218
  metadataStore: this._metadataStore,
223
- snapshotManager,
224
219
  gossip,
225
220
  presence,
226
- memberKey: this._signingContext.identityKey,
227
221
  keyring: this._keyring,
228
222
  feedStore: this._feedStore,
229
223
  signingContext: this._signingContext,
230
- snapshotId: metadata.snapshot,
231
224
  callbacks: {
232
225
  beforeReady: async () => {
233
226
  log('before space ready', { space: space.key });
234
227
  this._dataServiceSubscriptions.registerSpace(
235
228
  space.key,
236
- dataSpace.dataPipeline.databaseBackend!.createDataServiceHost()
229
+ dataSpace.dataPipeline.databaseHost!.createDataServiceHost(),
237
230
  );
238
231
  },
239
232
  afterReady: async () => {
@@ -241,8 +234,9 @@ export class DataSpaceManager {
241
234
  if (this._isOpen) {
242
235
  this.updated.emit();
243
236
  }
244
- }
245
- }
237
+ },
238
+ },
239
+ cache: metadata.cache,
246
240
  });
247
241
 
248
242
  await dataSpace.open();