@dxos/client-services 0.1.58-main.cbf3753 → 0.1.58-main.d5c2212

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 (72) hide show
  1. package/dist/lib/browser/{chunk-HBVO7V6N.mjs → chunk-X5NQYRFH.mjs} +253 -179
  2. package/dist/lib/browser/chunk-X5NQYRFH.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +11 -11
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/packlets/testing/index.mjs +5 -5
  7. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/index.cjs +301 -227
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/packlets/testing/index.cjs +298 -224
  12. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  13. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  14. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  15. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +1 -1
  16. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  17. package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +1 -1
  18. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +3 -3
  19. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  20. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  21. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -1
  22. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  23. package/dist/types/src/packlets/services/diagnostics.d.ts.map +1 -1
  24. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  25. package/dist/types/src/packlets/services/service-host.d.ts +1 -0
  26. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  27. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  28. package/dist/types/src/packlets/spaces/data-space.d.ts +1 -1
  29. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  30. package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
  31. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  32. package/dist/types/src/packlets/testing/invitation-utils.d.ts +5 -5
  33. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  34. package/dist/types/src/packlets/testing/test-builder.d.ts +1 -1
  35. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  36. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
  37. package/dist/types/src/packlets/vault/shell-runtime.d.ts +1 -1
  38. package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -1
  39. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  40. package/dist/types/src/version.d.ts +1 -1
  41. package/package.json +35 -35
  42. package/src/packlets/devices/devices-service.test.ts +1 -1
  43. package/src/packlets/devtools/devtools.ts +1 -1
  44. package/src/packlets/identity/authenticator.ts +2 -5
  45. package/src/packlets/identity/identity-manager.test.ts +1 -1
  46. package/src/packlets/identity/identity-service.test.ts +1 -1
  47. package/src/packlets/identity/identity.test.ts +1 -1
  48. package/src/packlets/invitations/device-invitation-protocol.ts +1 -1
  49. package/src/packlets/invitations/invitation-extension.ts +1 -2
  50. package/src/packlets/invitations/invitations-handler.ts +7 -8
  51. package/src/packlets/invitations/invitations-service.ts +5 -5
  52. package/src/packlets/invitations/space-invitation-protocol.ts +1 -1
  53. package/src/packlets/network/network-service.test.ts +1 -1
  54. package/src/packlets/services/diagnostics.ts +2 -2
  55. package/src/packlets/services/service-context.ts +7 -13
  56. package/src/packlets/services/service-host.test.ts +3 -3
  57. package/src/packlets/services/service-host.ts +42 -6
  58. package/src/packlets/services/service-registry.test.ts +1 -1
  59. package/src/packlets/spaces/data-space-manager.test.ts +1 -1
  60. package/src/packlets/spaces/data-space-manager.ts +1 -1
  61. package/src/packlets/spaces/data-space.ts +11 -3
  62. package/src/packlets/spaces/spaces-service.test.ts +1 -1
  63. package/src/packlets/spaces/spaces-service.ts +31 -10
  64. package/src/packlets/storage/storage.ts +10 -10
  65. package/src/packlets/testing/invitation-utils.ts +9 -9
  66. package/src/packlets/testing/test-builder.ts +3 -3
  67. package/src/packlets/vault/iframe-host-runtime.ts +1 -1
  68. package/src/packlets/vault/iframe-proxy-runtime.ts +1 -1
  69. package/src/packlets/vault/shell-runtime.ts +4 -4
  70. package/src/packlets/vault/worker-runtime.ts +9 -6
  71. package/src/version.ts +1 -1
  72. package/dist/lib/browser/chunk-HBVO7V6N.mjs.map +0 -7
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Event } from '@dxos/async';
6
- import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from '@dxos/client-protocol';
6
+ import { AuthenticatingInvitation, CancellableInvitation } from '@dxos/client-protocol';
7
7
  import { Stream } from '@dxos/codec-protobuf';
8
8
  import { invariant } from '@dxos/invariant';
9
9
  import { log } from '@dxos/log';
@@ -21,8 +21,8 @@ import { InvitationsHandler } from './invitations-handler';
21
21
  * Adapts invitation service observable to client/service stream.
22
22
  */
23
23
  export class InvitationsServiceImpl implements InvitationsService {
24
- private readonly _createInvitations = new Map<string, CancellableInvitationObservable>();
25
- private readonly _acceptInvitations = new Map<string, AuthenticatingInvitationObservable>();
24
+ private readonly _createInvitations = new Map<string, CancellableInvitation>();
25
+ private readonly _acceptInvitations = new Map<string, AuthenticatingInvitation>();
26
26
  private readonly _invitationCreated = new Event<Invitation>();
27
27
  private readonly _invitationAccepted = new Event<Invitation>();
28
28
  private readonly _removedCreated = new Event<Invitation>();
@@ -41,7 +41,7 @@ export class InvitationsServiceImpl implements InvitationsService {
41
41
  }
42
42
 
43
43
  createInvitation(options: Invitation): Stream<Invitation> {
44
- let invitation: CancellableInvitationObservable;
44
+ let invitation: CancellableInvitation;
45
45
 
46
46
  const existingInvitation = this._createInvitations.get(options.invitationId);
47
47
  if (existingInvitation) {
@@ -73,7 +73,7 @@ export class InvitationsServiceImpl implements InvitationsService {
73
73
  }
74
74
 
75
75
  acceptInvitation(options: Invitation): Stream<Invitation> {
76
- let invitation: AuthenticatingInvitationObservable;
76
+ let invitation: AuthenticatingInvitation;
77
77
 
78
78
  const existingInvitation = this._acceptInvitations.get(options.invitationId);
79
79
  if (existingInvitation) {
@@ -13,8 +13,8 @@ import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
13
13
  import { ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
14
14
  import { AdmissionRequest, AdmissionResponse, IntroductionRequest } from '@dxos/protocols/proto/dxos/halo/invitations';
15
15
 
16
- import { DataSpaceManager, SigningContext } from '../spaces';
17
16
  import { InvitationProtocol } from './invitation-protocol';
17
+ import { DataSpaceManager, SigningContext } from '../spaces';
18
18
 
19
19
  export class SpaceInvitationProtocol implements InvitationProtocol {
20
20
  constructor(
@@ -9,9 +9,9 @@ import { Context } from '@dxos/context';
9
9
  import { NetworkService, ConnectionState } from '@dxos/protocols/proto/dxos/client/services';
10
10
  import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
11
11
 
12
+ import { NetworkServiceImpl } from './network-service';
12
13
  import { ServiceContext } from '../services';
13
14
  import { createServiceContext } from '../testing';
14
- import { NetworkServiceImpl } from './network-service';
15
15
 
16
16
  describe('NetworkService', () => {
17
17
  let serviceContext: ServiceContext;
@@ -22,10 +22,10 @@ import {
22
22
  import { SubscribeToFeedsResponse } from '@dxos/protocols/proto/dxos/devtools/host';
23
23
  import { Epoch } from '@dxos/protocols/proto/dxos/halo/credentials';
24
24
 
25
- import { DXOS_VERSION } from '../../version';
26
- import { DataSpace } from '../spaces';
27
25
  import { getPlatform, Platform } from './platform';
28
26
  import { ServiceContext } from './service-context';
27
+ import { DXOS_VERSION } from '../../version';
28
+ import { DataSpace } from '../spaces';
29
29
 
30
30
  const DEFAULT_TIMEOUT = 1_000;
31
31
 
@@ -21,7 +21,7 @@ import { log } from '@dxos/log';
21
21
  import { SignalManager } from '@dxos/messaging';
22
22
  import { ModelFactory } from '@dxos/model-factory';
23
23
  import { NetworkManager } from '@dxos/network-manager';
24
- import { STORAGE_VERSION, trace } from '@dxos/protocols';
24
+ import { InvalidStorageVersionError, STORAGE_VERSION, trace } from '@dxos/protocols';
25
25
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
26
26
  import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
27
27
  import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
@@ -73,12 +73,11 @@ export class ServiceContext {
73
73
 
74
74
  private readonly _instanceId = PublicKey.random().toHex();
75
75
 
76
- // prettier-ignore
77
76
  constructor(
78
77
  public readonly storage: Storage,
79
78
  public readonly networkManager: NetworkManager,
80
79
  public readonly signalManager: SignalManager,
81
- public readonly modelFactory: ModelFactory
80
+ public readonly modelFactory: ModelFactory,
82
81
  ) {
83
82
  // TODO(burdon): Move strings to constants.
84
83
  this.metadataStore = new MetadataStore(storage.createDirectory('metadata'));
@@ -94,7 +93,7 @@ export class ServiceContext {
94
93
  valueEncoding,
95
94
  stats: true,
96
95
  },
97
- })
96
+ }),
98
97
  });
99
98
 
100
99
  this.spaceManager = new SpaceManager({
@@ -106,12 +105,7 @@ export class ServiceContext {
106
105
  snapshotStore: this.snapshotStore,
107
106
  });
108
107
 
109
- this.identityManager = new IdentityManager(
110
- this.metadataStore,
111
- this.keyring,
112
- this.feedStore,
113
- this.spaceManager
114
- );
108
+ this.identityManager = new IdentityManager(this.metadataStore, this.keyring, this.feedStore, this.spaceManager);
115
109
 
116
110
  this.invitations = new InvitationsHandler(this.networkManager);
117
111
 
@@ -123,8 +117,8 @@ export class ServiceContext {
123
117
  new DeviceInvitationProtocol(
124
118
  this.keyring,
125
119
  () => this.identityManager.identity ?? failUndefined(),
126
- this._acceptIdentity.bind(this)
127
- )
120
+ this._acceptIdentity.bind(this),
121
+ ),
128
122
  );
129
123
  }
130
124
 
@@ -184,7 +178,7 @@ export class ServiceContext {
184
178
  private async _checkStorageVersion() {
185
179
  await this.metadataStore.load();
186
180
  if (this.metadataStore.version !== STORAGE_VERSION) {
187
- throw new Error(`Invalid storage version: current=${this.metadataStore.version}, expected=${STORAGE_VERSION}`);
181
+ throw new InvalidStorageVersionError(STORAGE_VERSION, this.metadataStore.version);
188
182
  // TODO(mykola): Migrate storage to a new version if incompatibility is detected.
189
183
  }
190
184
  }
@@ -22,11 +22,11 @@ import { createMockCredential, createServiceHost } from '../testing';
22
22
  chai.use(chaiAsPromised);
23
23
 
24
24
  describe('ClientServicesHost', () => {
25
- const persistentStoragePath = '/tmp/dxos/client-services/service-host/storage';
25
+ const dataRoot = '/tmp/dxos/client-services/service-host/storage';
26
26
 
27
27
  afterEach(async () => {
28
28
  // Clean up.
29
- isNode() && rmSync(persistentStoragePath, { recursive: true, force: true });
29
+ isNode() && rmSync(dataRoot, { recursive: true, force: true });
30
30
  });
31
31
 
32
32
  test('queryCredentials', async () => {
@@ -114,7 +114,7 @@ describe('ClientServicesHost', () => {
114
114
 
115
115
  test('storage reset', async () => {
116
116
  const config = new Config({
117
- runtime: { client: { storage: { persistent: true, path: persistentStoragePath } } },
117
+ runtime: { client: { storage: { persistent: true, dataRoot } } },
118
118
  });
119
119
  {
120
120
  const host = createServiceHost(config, new MemorySignalManagerContext());
@@ -3,11 +3,12 @@
3
3
  //
4
4
 
5
5
  import { Event, synchronized } from '@dxos/async';
6
- import { clientServiceBundle, ClientServices } from '@dxos/client-protocol';
6
+ import { clientServiceBundle, ClientServices, defaultKey, Properties } from '@dxos/client-protocol';
7
7
  import { Config } from '@dxos/config';
8
8
  import { Context } from '@dxos/context';
9
9
  import { DocumentModel } from '@dxos/document-model';
10
10
  import { DataServiceImpl } from '@dxos/echo-pipeline';
11
+ import { TypedObject, base } from '@dxos/echo-schema';
11
12
  import { invariant } from '@dxos/invariant';
12
13
  import { PublicKey } from '@dxos/keys';
13
14
  import { log } from '@dxos/log';
@@ -16,14 +17,18 @@ import { ModelFactory } from '@dxos/model-factory';
16
17
  import { createSimplePeerTransportFactory, NetworkManager, TransportFactory } from '@dxos/network-manager';
17
18
  import { trace } from '@dxos/protocols';
18
19
  import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
20
+ import { EchoObject } from '@dxos/protocols/proto/dxos/echo/object';
19
21
  import { Storage } from '@dxos/random-access-storage';
20
22
  import { TextModel } from '@dxos/text-model';
21
23
  import { TRACE_PROCESSOR, trace as Trace } from '@dxos/tracing';
22
24
  import { WebsocketRpcClient } from '@dxos/websocket-rpc';
23
25
 
26
+ import { createDiagnostics } from './diagnostics';
27
+ import { ServiceContext } from './service-context';
28
+ import { ServiceRegistry } from './service-registry';
24
29
  import { DevicesServiceImpl } from '../devices';
25
30
  import { DevtoolsServiceImpl, DevtoolsHostEvents } from '../devtools';
26
- import { IdentityServiceImpl } from '../identity';
31
+ import { CreateIdentityOptions, IdentityServiceImpl } from '../identity';
27
32
  import { InvitationsServiceImpl } from '../invitations';
28
33
  import { Lock, ResourceLock } from '../locks';
29
34
  import { LoggingServiceImpl } from '../logging';
@@ -31,15 +36,27 @@ import { NetworkServiceImpl } from '../network';
31
36
  import { SpacesServiceImpl } from '../spaces';
32
37
  import { createStorageObjects } from '../storage';
33
38
  import { SystemServiceImpl } from '../system';
34
- import { createDiagnostics } from './diagnostics';
35
- import { ServiceContext } from './service-context';
36
- import { ServiceRegistry } from './service-registry';
37
39
 
38
40
  // TODO(burdon): Factor out to spaces.
39
41
  export const createDefaultModelFactory = () => {
40
42
  return new ModelFactory().registerModel(DocumentModel).registerModel(TextModel);
41
43
  };
42
44
 
45
+ // TODO(wittjosiah): Factor out.
46
+ const createGenesisMutationFromTypedObject = (obj: TypedObject): EchoObject => {
47
+ const snapshot = obj[base]._createSnapshot();
48
+
49
+ return {
50
+ objectId: obj[base]._id,
51
+ genesis: {
52
+ modelType: obj[base]._modelConstructor.meta.type,
53
+ },
54
+ snapshot: {
55
+ model: snapshot,
56
+ },
57
+ };
58
+ };
59
+
43
60
  export type ClientServicesHostParams = {
44
61
  /**
45
62
  * Can be omitted if `initialize` is later called.
@@ -243,7 +260,7 @@ export class ClientServicesHost {
243
260
  SystemService: this._systemService,
244
261
 
245
262
  IdentityService: new IdentityServiceImpl(
246
- (params) => this._serviceContext.createIdentity(params),
263
+ (params) => this._createIdentity(params),
247
264
  this._serviceContext.identityManager,
248
265
  this._serviceContext.keyring,
249
266
  ),
@@ -329,4 +346,23 @@ export class ClientServicesHost {
329
346
  log.trace('dxos.sdk.client-services-host.reset', trace.end({ id: traceId }));
330
347
  await this._callbacks?.onReset?.();
331
348
  }
349
+
350
+ private async _createIdentity(params?: CreateIdentityOptions) {
351
+ const identity = await this._serviceContext.createIdentity(params);
352
+
353
+ // Setup default space.
354
+ await this._serviceContext.initialized.wait();
355
+ const space = await this._serviceContext.dataSpaceManager!.createSpace();
356
+ const obj: TypedObject = new Properties();
357
+ obj[defaultKey] = identity.identityKey.toHex();
358
+ await this._serviceRegistry.services.DataService!.write({
359
+ spaceKey: space.key,
360
+ batch: {
361
+ objects: [createGenesisMutationFromTypedObject(obj)],
362
+ },
363
+ });
364
+ await this._serviceRegistry.services.DataService!.flush({ spaceKey: space.key });
365
+
366
+ return identity;
367
+ }
332
368
  }
@@ -14,9 +14,9 @@ import { SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/s
14
14
  import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
15
15
  import { describe, test } from '@dxos/test';
16
16
 
17
+ import { ServiceRegistry } from './service-registry';
17
18
  import { SystemServiceImpl } from '../system';
18
19
  import { createServiceContext } from '../testing';
19
- import { ServiceRegistry } from './service-registry';
20
20
 
21
21
  // TODO(burdon): Create TestService (that doesn't require peers).
22
22
 
@@ -164,7 +164,7 @@ describe('DataSpaceManager', () => {
164
164
  afterTest(async () => builder.destroy());
165
165
 
166
166
  const peer = builder.createPeer({
167
- storageType: typeof window === 'undefined' ? StorageType.NODE : StorageType.WEBFS,
167
+ dataStore: typeof window === 'undefined' ? StorageType.NODE : StorageType.WEBFS,
168
168
  });
169
169
  await peer.createIdentity();
170
170
  await openAndClose(peer.dataSpaceManager);
@@ -20,9 +20,9 @@ import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
20
20
  import { Timeframe } from '@dxos/timeframe';
21
21
  import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
22
22
 
23
- import { createAuthProvider } from '../identity';
24
23
  import { DataSpace } from './data-space';
25
24
  import { spaceGenesis } from './genesis';
25
+ import { createAuthProvider } from '../identity';
26
26
 
27
27
  export interface SigningContext {
28
28
  identityKey: PublicKey;
@@ -7,11 +7,11 @@ import { AUTH_TIMEOUT } from '@dxos/client-protocol';
7
7
  import { cancelWithContext, Context } from '@dxos/context';
8
8
  import { timed } from '@dxos/debug';
9
9
  import { MetadataStore, Space, createMappedFeedWriter, DataPipeline } from '@dxos/echo-pipeline';
10
- import { CancelledError, SystemError } from '@dxos/errors';
11
10
  import { FeedStore } from '@dxos/feed-store';
12
11
  import { Keyring } from '@dxos/keyring';
13
12
  import { PublicKey } from '@dxos/keys';
14
13
  import { log } from '@dxos/log';
14
+ import { CancelledError, SystemError } from '@dxos/protocols';
15
15
  import { SpaceState, Space as SpaceProto } from '@dxos/protocols/proto/dxos/client/services';
16
16
  import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
17
17
  import { SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
@@ -22,9 +22,9 @@ import { Timeframe } from '@dxos/timeframe';
22
22
  import { trace } from '@dxos/tracing';
23
23
  import { ComplexSet } from '@dxos/util';
24
24
 
25
- import { TrustedKeySetAuthVerifier } from '../identity';
26
25
  import { SigningContext } from './data-space-manager';
27
26
  import { NotarizationPlugin } from './notarization-plugin';
27
+ import { TrustedKeySetAuthVerifier } from '../identity';
28
28
 
29
29
  export type DataSpaceCallbacks = {
30
30
  /**
@@ -101,7 +101,13 @@ export class DataSpace {
101
101
  this._callbacks = params.callbacks ?? {};
102
102
 
103
103
  this.authVerifier = new TrustedKeySetAuthVerifier({
104
- trustedKeysProvider: () => new ComplexSet(PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
104
+ trustedKeysProvider: () =>
105
+ new ComplexSet(
106
+ PublicKey.hash,
107
+ Array.from(this._inner.spaceState.members.values())
108
+ .filter((member) => !member.removed)
109
+ .map((member) => member.key),
110
+ ),
105
111
  update: this._inner.stateUpdate,
106
112
  authTimeout: AUTH_TIMEOUT,
107
113
  });
@@ -151,6 +157,7 @@ export class DataSpace {
151
157
  }
152
158
 
153
159
  private async _open() {
160
+ await this._gossip.open();
154
161
  await this._notarizationPlugin.open();
155
162
  await this._inner.spaceState.addCredentialProcessor(this._notarizationPlugin);
156
163
  await this._inner.open(new Context());
@@ -180,6 +187,7 @@ export class DataSpace {
180
187
  await this._notarizationPlugin.close();
181
188
 
182
189
  await this._presence.destroy();
190
+ await this._gossip.close();
183
191
  }
184
192
 
185
193
  async postMessage(channel: string, message: any) {
@@ -11,9 +11,9 @@ import { PublicKey } from '@dxos/keys';
11
11
  import { Space, SpacesService } from '@dxos/protocols/proto/dxos/client/services';
12
12
  import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
13
13
 
14
+ import { SpacesServiceImpl } from './spaces-service';
14
15
  import { ServiceContext } from '../services';
15
16
  import { createServiceContext } from '../testing';
16
- import { SpacesServiceImpl } from './spaces-service';
17
17
 
18
18
  chai.use(chaiAsPromised);
19
19
 
@@ -6,10 +6,10 @@ import { EventSubscriptions, UpdateScheduler, scheduleTask } from '@dxos/async';
6
6
  import { Stream } from '@dxos/codec-protobuf';
7
7
  import { CredentialProcessor } from '@dxos/credentials';
8
8
  import { raise } from '@dxos/debug';
9
- import { DataServiceSubscriptions, SpaceManager, SpaceNotFoundError } from '@dxos/echo-pipeline';
10
- import { ApiError } from '@dxos/errors';
9
+ import { DataServiceSubscriptions, SpaceManager } from '@dxos/echo-pipeline';
10
+ import { invariant } from '@dxos/invariant';
11
11
  import { log } from '@dxos/log';
12
- import { encodeError } from '@dxos/protocols';
12
+ import { ApiError, SpaceNotFoundError, encodeError } from '@dxos/protocols';
13
13
  import {
14
14
  CreateEpochRequest,
15
15
  PostMessageRequest,
@@ -27,9 +27,9 @@ import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
27
27
  import { GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
28
28
  import { Provider } from '@dxos/util';
29
29
 
30
- import { IdentityManager } from '../identity';
31
30
  import { DataSpace } from './data-space';
32
31
  import { DataSpaceManager } from './data-space-manager';
32
+ import { IdentityManager } from '../identity';
33
33
 
34
34
  export class SpacesServiceImpl implements SpacesService {
35
35
  constructor(
@@ -99,7 +99,7 @@ export class SpacesServiceImpl implements SpacesService {
99
99
  subscriptions.add(space.dataPipeline.onNewEpoch.on(ctx, () => scheduler.trigger()));
100
100
 
101
101
  // Pipeline progress.
102
- space.inner.controlPipeline.state.timeframeUpdate.on(ctx, () => scheduler.trigger());
102
+ subscriptions.add(space.inner.controlPipeline.state.timeframeUpdate.on(ctx, () => scheduler.trigger()));
103
103
  if (space.dataPipeline.pipelineState) {
104
104
  subscriptions.add(space.dataPipeline.pipelineState.timeframeUpdate.on(ctx, () => scheduler.trigger()));
105
105
  }
@@ -140,8 +140,8 @@ export class SpacesServiceImpl implements SpacesService {
140
140
  });
141
141
  }
142
142
 
143
- queryCredentials({ spaceKey }: QueryCredentialsRequest): Stream<Credential> {
144
- return new Stream(({ ctx, next }) => {
143
+ queryCredentials({ spaceKey, noTail }: QueryCredentialsRequest): Stream<Credential> {
144
+ return new Stream(({ ctx, next, close }) => {
145
145
  const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
146
146
 
147
147
  const processor: CredentialProcessor = {
@@ -150,14 +150,31 @@ export class SpacesServiceImpl implements SpacesService {
150
150
  },
151
151
  };
152
152
  ctx.onDispose(() => space.spaceState.removeCredentialProcessor(processor));
153
- scheduleTask(ctx, () => space.spaceState.addCredentialProcessor(processor));
153
+ scheduleTask(ctx, async () => {
154
+ await space.spaceState.addCredentialProcessor(processor);
155
+ if (noTail) {
156
+ close();
157
+ }
158
+ });
154
159
  });
155
160
  }
156
161
 
157
162
  async writeCredentials({ spaceKey, credentials }: WriteCredentialsRequest) {
158
163
  const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
159
164
  for (const credential of credentials ?? []) {
160
- await space.controlPipeline.writer.write({ credential: { credential } });
165
+ if (credential.proof) {
166
+ await space.controlPipeline.writer.write({ credential: { credential } });
167
+ } else {
168
+ invariant(!credential.id, 'Id on unsigned credentials is not allowed');
169
+ invariant(this._identityManager.identity, 'Identity is not available');
170
+ const signer = this._identityManager.identity.getIdentityCredentialSigner();
171
+ invariant(credential.issuer.equals(signer.getIssuer()));
172
+ const signedCredential = await signer.createCredential({
173
+ subject: credential.subject.id,
174
+ assertion: credential.subject.assertion,
175
+ });
176
+ await space.controlPipeline.writer.write({ credential: { credential: signedCredential } });
177
+ }
161
178
  }
162
179
  }
163
180
 
@@ -202,7 +219,11 @@ export class SpacesServiceImpl implements SpacesService {
202
219
  displayName: member.assertion.profile?.displayName,
203
220
  },
204
221
  },
205
- presence: isMe || peers.length > 0 ? SpaceMember.PresenceState.ONLINE : SpaceMember.PresenceState.OFFLINE,
222
+ presence: member.removed
223
+ ? SpaceMember.PresenceState.REMOVED
224
+ : isMe || peers.length > 0
225
+ ? SpaceMember.PresenceState.ONLINE
226
+ : SpaceMember.PresenceState.OFFLINE,
206
227
  peerStates: peers,
207
228
  };
208
229
  }),
@@ -5,7 +5,7 @@
5
5
  //
6
6
 
7
7
  import { DX_DATA } from '@dxos/client-protocol';
8
- import { InvalidConfigError } from '@dxos/errors';
8
+ import { InvalidConfigError } from '@dxos/protocols';
9
9
  import { Runtime } from '@dxos/protocols/proto/dxos/config';
10
10
  import { createStorage, StorageType } from '@dxos/random-access-storage';
11
11
  import { isNode } from '@dxos/util';
@@ -15,29 +15,29 @@ import StorageDriver = Runtime.Client.Storage.StorageDriver;
15
15
  // TODO(burdon): Factor out.
16
16
  export const createStorageObjects = (config: Runtime.Client.Storage) => {
17
17
  const {
18
- path = isNode() ? DX_DATA : 'dxos/storage', // TODO(burdon): Factor out const.
19
- storageType,
20
- keyStorage,
21
18
  persistent = false,
19
+ keyStore,
20
+ dataStore,
21
+ dataRoot = isNode() ? DX_DATA : 'dxos/storage', // TODO(burdon): Factor out const.
22
22
  } = config ?? {};
23
23
 
24
- if (persistent && storageType === StorageDriver.RAM) {
24
+ if (persistent && dataStore === StorageDriver.RAM) {
25
25
  throw new InvalidConfigError('RAM storage cannot be used in persistent mode.');
26
26
  }
27
- if (!persistent && storageType !== undefined && storageType !== StorageDriver.RAM) {
27
+ if (!persistent && dataStore !== undefined && dataStore !== StorageDriver.RAM) {
28
28
  throw new InvalidConfigError('Cannot use a persistent storage in not persistent mode.');
29
29
  }
30
- if (persistent && keyStorage === StorageDriver.RAM) {
30
+ if (persistent && keyStore === StorageDriver.RAM) {
31
31
  throw new InvalidConfigError('RAM key storage cannot be used in persistent mode.');
32
32
  }
33
- if (!persistent && keyStorage !== StorageDriver.RAM && keyStorage !== undefined) {
33
+ if (!persistent && keyStore !== StorageDriver.RAM && keyStore !== undefined) {
34
34
  throw new InvalidConfigError('Cannot use a persistent key storage in not persistent mode.');
35
35
  }
36
36
 
37
37
  return {
38
38
  storage: createStorage({
39
- type: persistent ? toStorageType(storageType) : StorageType.RAM,
40
- root: `${path}/`,
39
+ type: persistent ? toStorageType(dataStore) : StorageType.RAM,
40
+ root: `${dataRoot}/`,
41
41
  }),
42
42
  };
43
43
  };
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
- import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from '@dxos/client-protocol';
6
+ import { AuthenticatingInvitation, CancellableInvitation } from '@dxos/client-protocol';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
9
9
 
@@ -25,11 +25,11 @@ export const sanitizeInvitation = (invitation: Invitation): Invitation => {
25
25
  };
26
26
 
27
27
  export type InvitationHost = {
28
- createInvitation(options?: Partial<Invitation>): CancellableInvitationObservable;
28
+ share(options?: Partial<Invitation>): CancellableInvitation;
29
29
  };
30
30
 
31
31
  export type InvitationGuest = {
32
- acceptInvitation(invitation: Invitation): AuthenticatingInvitationObservable;
32
+ join(invitation: Invitation | string): AuthenticatingInvitation;
33
33
  };
34
34
 
35
35
  export type PerformInvitationCallbacks<T> = {
@@ -48,8 +48,8 @@ export type PerformInvitationParams = {
48
48
  guest: ServiceContext | InvitationGuest;
49
49
  options?: Partial<Invitation>;
50
50
  hooks?: {
51
- host?: PerformInvitationCallbacks<CancellableInvitationObservable>;
52
- guest?: PerformInvitationCallbacks<AuthenticatingInvitationObservable>;
51
+ host?: PerformInvitationCallbacks<CancellableInvitation>;
52
+ guest?: PerformInvitationCallbacks<AuthenticatingInvitation>;
53
53
  };
54
54
  };
55
55
 
@@ -196,7 +196,7 @@ export const performInvitation = ({
196
196
  const createInvitation = (
197
197
  host: ServiceContext | InvitationHost,
198
198
  options?: Partial<Invitation>,
199
- ): CancellableInvitationObservable => {
199
+ ): CancellableInvitation => {
200
200
  options ??= {
201
201
  authMethod: Invitation.AuthMethod.NONE,
202
202
  ...(options ?? {}),
@@ -207,13 +207,13 @@ const createInvitation = (
207
207
  return host.invitations.createInvitation(hostHandler, options);
208
208
  }
209
209
 
210
- return host.createInvitation(options);
210
+ return host.share(options);
211
211
  };
212
212
 
213
213
  const acceptInvitation = (
214
214
  guest: ServiceContext | InvitationGuest,
215
215
  invitation: Invitation,
216
- ): AuthenticatingInvitationObservable => {
216
+ ): AuthenticatingInvitation => {
217
217
  invitation = sanitizeInvitation(invitation);
218
218
 
219
219
  if (guest instanceof ServiceContext) {
@@ -221,5 +221,5 @@ const acceptInvitation = (
221
221
  return guest.invitations.acceptInvitation(guestHandler, invitation);
222
222
  }
223
223
 
224
- return guest.acceptInvitation(invitation);
224
+ return guest.join(invitation);
225
225
  };
@@ -94,7 +94,7 @@ export class TestBuilder {
94
94
  }
95
95
 
96
96
  export type TestPeerOpts = {
97
- storageType?: StorageType;
97
+ dataStore?: StorageType;
98
98
  };
99
99
 
100
100
  export type TestPeerProps = {
@@ -115,7 +115,7 @@ export class TestPeer {
115
115
 
116
116
  constructor(
117
117
  private readonly signalContext: MemorySignalManagerContext,
118
- private readonly opts: TestPeerOpts = { storageType: StorageType.RAM },
118
+ private readonly opts: TestPeerOpts = { dataStore: StorageType.RAM },
119
119
  ) {}
120
120
 
121
121
  get props() {
@@ -123,7 +123,7 @@ export class TestPeer {
123
123
  }
124
124
 
125
125
  get storage() {
126
- return (this._props.storage ??= createStorage({ type: this.opts.storageType }));
126
+ return (this._props.storage ??= createStorage({ type: this.opts.dataStore }));
127
127
  }
128
128
 
129
129
  get keyring() {
@@ -12,9 +12,9 @@ import { createSimplePeerTransportFactory, TransportFactory } from '@dxos/networ
12
12
  import { RpcPort } from '@dxos/rpc';
13
13
  import { getAsyncValue, MaybePromise, Provider } from '@dxos/util';
14
14
 
15
+ import { ShellRuntimeImpl } from './shell-runtime';
15
16
  import { ClientServicesHost } from '../services';
16
17
  import { ClientRpcServer, ClientRpcServerParams } from '../services/client-rpc-server';
17
- import { ShellRuntimeImpl } from './shell-runtime';
18
18
 
19
19
  const LOCK_KEY = 'DXOS_RESOURCE_LOCK';
20
20
 
@@ -5,9 +5,9 @@
5
5
  import { Trigger } from '@dxos/async';
6
6
  import { iframeServiceBundle, ShellRuntime, workerServiceBundle, WorkerServiceBundle } from '@dxos/client-protocol';
7
7
  import { Config } from '@dxos/config';
8
- import { RemoteServiceConnectionError } from '@dxos/errors';
9
8
  import { log } from '@dxos/log';
10
9
  import { SimplePeerTransportService } from '@dxos/network-manager';
10
+ import { RemoteServiceConnectionError } from '@dxos/protocols';
11
11
  import { BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
12
12
  import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
13
13
  import { getAsyncValue, MaybePromise, Provider } from '@dxos/util';
@@ -33,11 +33,11 @@ export class ShellRuntimeImpl implements ShellRuntime {
33
33
  return this._spaceKey;
34
34
  }
35
35
 
36
- setLayout(layout: ShellLayout, options: Omit<LayoutRequest, 'layout'> = {}) {
36
+ setLayout({ layout, invitationCode, spaceKey }: LayoutRequest) {
37
37
  this._layout = layout;
38
- this._invitationCode = options.invitationCode;
39
- this._spaceKey = options.spaceKey;
40
- this.layoutUpdate.emit({ layout, ...options });
38
+ this._invitationCode = invitationCode;
39
+ this._spaceKey = spaceKey;
40
+ this.layoutUpdate.emit({ layout, invitationCode, spaceKey });
41
41
  }
42
42
 
43
43
  async setAppContext(context: AppContextRequest) {