@dxos/client-services 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8

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 (101) hide show
  1. package/dist/lib/browser/{chunk-27A4ATQX.mjs → chunk-Z6PWUKRZ.mjs} +364 -248
  2. package/dist/lib/browser/chunk-Z6PWUKRZ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -1
  6. package/dist/lib/node/{chunk-7FKXMJDD.cjs → chunk-PK4NC3T7.cjs} +389 -273
  7. package/dist/lib/node/chunk-PK4NC3T7.cjs.map +7 -0
  8. package/dist/lib/node/index.cjs +47 -47
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/testing/index.cjs +8 -8
  11. package/dist/lib/node-esm/{chunk-HGN7FHFK.mjs → chunk-2FL5LYPQ.mjs} +364 -248
  12. package/dist/lib/node-esm/chunk-2FL5LYPQ.mjs.map +7 -0
  13. package/dist/lib/node-esm/index.mjs +1 -1
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +1 -1
  16. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  17. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
  18. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  19. package/dist/types/src/packlets/devices/devices-service.d.ts +1 -1
  20. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  21. package/dist/types/src/packlets/devtools/devtools.d.ts +1 -1
  22. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  23. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  24. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  25. package/dist/types/src/packlets/devtools/keys.d.ts +1 -1
  26. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  27. package/dist/types/src/packlets/devtools/metadata.d.ts +1 -1
  28. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  29. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  30. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  31. package/dist/types/src/packlets/devtools/spaces.d.ts +1 -1
  32. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  33. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  34. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  35. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  36. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  37. package/dist/types/src/packlets/identity/identity-manager.d.ts +0 -3
  38. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  39. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +12 -4
  40. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  41. package/dist/types/src/packlets/identity/identity-service.d.ts +9 -4
  42. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  43. package/dist/types/src/packlets/identity/identity.d.ts +3 -1
  44. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  45. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  46. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  47. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  49. package/dist/types/src/packlets/invitations/utils.d.ts +1 -0
  50. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  51. package/dist/types/src/packlets/logging/logging-service.d.ts +1 -1
  52. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  53. package/dist/types/src/packlets/network/network-service.d.ts +9 -2
  54. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  55. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  56. package/dist/types/src/packlets/services/service-host.d.ts +1 -1
  57. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  58. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +3 -0
  59. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  60. package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
  61. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  62. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  63. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  64. package/dist/types/src/version.d.ts +1 -1
  65. package/dist/types/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +39 -38
  67. package/src/packlets/agents/edge-agent-manager.ts +6 -0
  68. package/src/packlets/agents/edge-agent-service.ts +1 -1
  69. package/src/packlets/devices/devices-service.ts +1 -1
  70. package/src/packlets/devtools/devtools.ts +1 -1
  71. package/src/packlets/devtools/feeds.ts +1 -1
  72. package/src/packlets/devtools/keys.ts +1 -1
  73. package/src/packlets/devtools/metadata.ts +1 -1
  74. package/src/packlets/devtools/network.ts +1 -1
  75. package/src/packlets/devtools/spaces.ts +1 -1
  76. package/src/packlets/diagnostics/diagnostics-collector.ts +2 -2
  77. package/src/packlets/diagnostics/diagnostics.ts +17 -13
  78. package/src/packlets/identity/contacts-service.ts +1 -1
  79. package/src/packlets/identity/identity-manager.ts +3 -29
  80. package/src/packlets/identity/identity-recovery-manager.ts +86 -9
  81. package/src/packlets/identity/identity-service.ts +17 -4
  82. package/src/packlets/identity/identity.test.ts +2 -1
  83. package/src/packlets/identity/identity.ts +4 -1
  84. package/src/packlets/invitations/invitations-handler.ts +15 -6
  85. package/src/packlets/invitations/invitations-manager.ts +1 -1
  86. package/src/packlets/invitations/invitations-service.ts +1 -1
  87. package/src/packlets/invitations/space-invitation-protocol.ts +2 -3
  88. package/src/packlets/invitations/utils.ts +7 -0
  89. package/src/packlets/logging/logging-service.ts +1 -1
  90. package/src/packlets/network/network-service.ts +39 -1
  91. package/src/packlets/services/service-context.ts +1 -0
  92. package/src/packlets/spaces/data-space-manager.ts +3 -3
  93. package/src/packlets/spaces/data-space.ts +2 -2
  94. package/src/packlets/spaces/edge-feed-replicator.ts +8 -8
  95. package/src/packlets/spaces/notarization-plugin.ts +32 -17
  96. package/src/packlets/spaces/spaces-service.ts +31 -21
  97. package/src/packlets/system/system-service.ts +1 -1
  98. package/src/version.ts +1 -1
  99. package/dist/lib/browser/chunk-27A4ATQX.mjs.map +0 -7
  100. package/dist/lib/node/chunk-7FKXMJDD.cjs.map +0 -7
  101. package/dist/lib/node-esm/chunk-HGN7FHFK.mjs.map +0 -7
@@ -28,6 +28,7 @@ import {
28
28
  } from '@dxos/protocols/proto/dxos/halo/invitations';
29
29
 
30
30
  import { type InvitationProtocol } from './invitation-protocol';
31
+ import { computeExpirationTime } from './utils';
31
32
  import { type DataSpaceManager, type SigningContext } from '../spaces';
32
33
 
33
34
  export class SpaceInvitationProtocol implements InvitationProtocol {
@@ -113,9 +114,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
113
114
  authMethod: invitation.authMethod,
114
115
  swarmKey: invitation.swarmKey,
115
116
  role: invitation.role ?? SpaceMember.Role.ADMIN,
116
- expiresOn: invitation.lifetime
117
- ? new Date((invitation.created?.getTime() ?? Date.now()) + invitation.lifetime)
118
- : undefined,
117
+ expiresOn: computeExpirationTime(invitation),
119
118
  multiUse: invitation.multiUse ?? false,
120
119
  guestKey:
121
120
  invitation.authMethod === Invitation.AuthMethod.KNOWN_PUBLIC_KEY
@@ -10,6 +10,13 @@ export const stateToString = (state: Invitation.State): string => {
10
10
  return Object.entries(Invitation.State).find(([key, val]) => val === state)?.[0] ?? 'unknown';
11
11
  };
12
12
 
13
+ export const computeExpirationTime = (invitation: Partial<Invitation>): Date | undefined => {
14
+ if (!invitation.lifetime) {
15
+ return;
16
+ }
17
+ return new Date((invitation.created?.getTime() ?? Date.now()) + invitation.lifetime * 1000);
18
+ };
19
+
13
20
  export const tryAcquireBeforeContextDisposed = async (ctx: Context, mutex: Mutex): Promise<MutexGuard> => {
14
21
  let guard: MutexGuard | undefined;
15
22
  return cancelWithContext(
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Event } from '@dxos/async';
6
- import { Stream } from '@dxos/codec-protobuf';
6
+ import { Stream } from '@dxos/codec-protobuf/stream';
7
7
  import { PublicKey } from '@dxos/keys';
8
8
  import {
9
9
  type LogLevel,
@@ -2,14 +2,17 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { Stream } from '@dxos/codec-protobuf';
5
+ import { Stream } from '@dxos/codec-protobuf/stream';
6
6
  import { type SignalManager } from '@dxos/messaging';
7
7
  import { type SwarmNetworkManager } from '@dxos/network-manager';
8
8
  import {
9
+ type SubscribeSwarmStateRequest,
9
10
  type NetworkService,
10
11
  type NetworkStatus,
11
12
  type UpdateConfigRequest,
12
13
  } from '@dxos/protocols/proto/dxos/client/services';
14
+ import { type Peer, type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
15
+ import { type LeaveRequest, type JoinRequest, type Message } from '@dxos/protocols/proto/dxos/edge/signal';
13
16
 
14
17
  export class NetworkServiceImpl implements NetworkService {
15
18
  constructor(
@@ -41,4 +44,39 @@ export class NetworkServiceImpl implements NetworkService {
41
44
  async updateConfig(request: UpdateConfigRequest) {
42
45
  await this.networkManager.setConnectionState(request.swarm);
43
46
  }
47
+
48
+ async joinSwarm(request: JoinRequest): Promise<void> {
49
+ return this.signalManager.join(request);
50
+ }
51
+
52
+ async leaveSwarm(request: LeaveRequest): Promise<void> {
53
+ return this.signalManager.leave(request);
54
+ }
55
+
56
+ subscribeSwarmState(request: SubscribeSwarmStateRequest): Stream<SwarmResponse> {
57
+ return new Stream<SwarmResponse>(({ next }) => {
58
+ const unsubscribe = this.signalManager.swarmState?.on((state) => {
59
+ if (request.topic.equals(state.swarmKey)) {
60
+ next(state);
61
+ }
62
+ });
63
+ return unsubscribe;
64
+ });
65
+ }
66
+
67
+ async sendMessage(message: Message): Promise<void> {
68
+ return this.signalManager.sendMessage(message);
69
+ }
70
+
71
+ subscribeMessages(peer: Peer): Stream<Message> {
72
+ return new Stream<Message>(({ next }) => {
73
+ const unsubscribe = this.signalManager.onMessage.on((message) => {
74
+ if (message.recipient.peerKey === peer.peerKey) {
75
+ next(message);
76
+ }
77
+ });
78
+
79
+ return unsubscribe;
80
+ });
81
+ }
44
82
  }
@@ -154,6 +154,7 @@ export class ServiceContext extends Resource {
154
154
  this.echoHost = new EchoHost({
155
155
  kv: this.level,
156
156
  peerIdProvider: () => this.identityManager.identity?.deviceKey?.toHex(),
157
+ getSpaceKeyByRootDocumentId: (documentId) => this.spaceManager.findSpaceByRootDocumentId(documentId)?.key,
157
158
  });
158
159
 
159
160
  this._meshReplicator = new MeshEchoReplicator();
@@ -503,7 +503,7 @@ export class DataSpaceManager extends Resource {
503
503
  });
504
504
  dataSpace.postOpen.append(async () => {
505
505
  const setting = dataSpace.getEdgeReplicationSetting();
506
- if (setting === EdgeReplicationSetting.ENABLED) {
506
+ if (!setting || setting === EdgeReplicationSetting.ENABLED) {
507
507
  await this._echoEdgeReplicator?.connectToSpace(dataSpace.id);
508
508
  } else if (this._echoEdgeReplicator) {
509
509
  log('not connecting EchoEdgeReplicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
@@ -511,7 +511,7 @@ export class DataSpaceManager extends Resource {
511
511
  });
512
512
  dataSpace.preClose.append(async () => {
513
513
  const setting = dataSpace.getEdgeReplicationSetting();
514
- if (setting === EdgeReplicationSetting.ENABLED) {
514
+ if (!setting || setting === EdgeReplicationSetting.ENABLED) {
515
515
  await this._echoEdgeReplicator?.disconnectFromSpace(dataSpace.id);
516
516
  }
517
517
  });
@@ -609,7 +609,7 @@ export class DataSpaceManager extends Resource {
609
609
  invitationId: invitation.invitationId,
610
610
  swarmKey: invitation.swarmKey,
611
611
  guestKeypair: invitation.guestKey ? { publicKey: invitation.guestKey } : undefined,
612
- lifetime: invitation.expiresOn ? invitation.expiresOn.getTime() - Date.now() : undefined,
612
+ lifetime: invitation.expiresOn ? (invitation.expiresOn.getTime() - Date.now()) / 1000 : undefined,
613
613
  multiUse: invitation.multiUse,
614
614
  delegationCredentialId: credentialId,
615
615
  persistent: false,
@@ -14,7 +14,7 @@ import {
14
14
  type MetadataStore,
15
15
  type Space,
16
16
  } from '@dxos/echo-pipeline';
17
- import { SpaceDocVersion } from '@dxos/echo-protocol';
17
+ import { SpaceDocVersion, type SpaceDoc } from '@dxos/echo-protocol';
18
18
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
19
19
  import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
20
20
  import { failedInvariant } from '@dxos/invariant';
@@ -446,7 +446,7 @@ export class DataSpace {
446
446
  private _onNewAutomergeRoot(rootUrl: string) {
447
447
  log('loading automerge root doc for space', { space: this.key, rootUrl });
448
448
 
449
- const handle = this._echoHost.automergeRepo.find(rootUrl as any);
449
+ const handle = this._echoHost.automergeRepo.find<SpaceDoc>(rootUrl as any);
450
450
 
451
451
  // TODO(dmaretskyi): Make this single-threaded (but doc loading should still be parallel to not block epoch processing).
452
452
  queueMicrotask(async () => {
@@ -117,7 +117,7 @@ export class EdgeFeedReplicator extends Resource {
117
117
  }
118
118
 
119
119
  async addFeed(feed: FeedWrapper<any>) {
120
- log.info('addFeed', { key: feed.key, connected: this._connected, hasConnectionCtx: !!this._connectionCtx });
120
+ log('addFeed', { key: feed.key, connected: this._connected, hasConnectionCtx: !!this._connectionCtx });
121
121
  this._feeds.set(feed.key, feed);
122
122
 
123
123
  if (this._connected && this._connectionCtx) {
@@ -143,12 +143,12 @@ export class EdgeFeedReplicator extends Resource {
143
143
 
144
144
  private async _sendMessage(message: ProtocolMessage) {
145
145
  if (!this._connectionCtx) {
146
- log.info('message dropped because connection was disposed');
146
+ log('message dropped because connection was disposed');
147
147
  return;
148
148
  }
149
149
 
150
150
  if (message.type === 'data') {
151
- log.info('sending blocks', {
151
+ log('sending blocks', {
152
152
  feedKey: message.feedKey,
153
153
  blocks: message.blocks.map((b) => b.index),
154
154
  });
@@ -191,7 +191,7 @@ export class EdgeFeedReplicator extends Resource {
191
191
 
192
192
  const logMeta = { localLength: feed.length, remoteLength: message.length, feedKey };
193
193
  if (message.length > feed.length) {
194
- log.info('requesting missing blocks', logMeta);
194
+ log('requesting missing blocks', logMeta);
195
195
 
196
196
  await this._sendMessage({
197
197
  type: 'request',
@@ -199,7 +199,7 @@ export class EdgeFeedReplicator extends Resource {
199
199
  range: { from: feed.length, to: message.length },
200
200
  });
201
201
  } else if (message.length < feed.length) {
202
- log.info('pushing blocks to remote', logMeta);
202
+ log('pushing blocks to remote', logMeta);
203
203
 
204
204
  await this._pushBlocks(feed, message.length, feed.length);
205
205
  }
@@ -208,7 +208,7 @@ export class EdgeFeedReplicator extends Resource {
208
208
  }
209
209
 
210
210
  case 'data': {
211
- log.info('received data', { feed: message.feedKey, blocks: message.blocks.map((b) => b.index) });
211
+ log('received data', { feed: message.feedKey, blocks: message.blocks.map((b) => b.index) });
212
212
 
213
213
  const feedKey = PublicKey.fromHex(message.feedKey);
214
214
  const feed = this._feeds.get(feedKey);
@@ -229,7 +229,7 @@ export class EdgeFeedReplicator extends Resource {
229
229
  }
230
230
 
231
231
  private async _pushBlocks(feed: FeedWrapper<any>, from: number, to: number) {
232
- log.info('pushing blocks', { feed: feed.key.toHex(), from, to });
232
+ log('pushing blocks', { feed: feed.key.toHex(), from, to });
233
233
 
234
234
  const blocks: FeedBlock[] = await Promise.all(
235
235
  rangeFromTo(from, to).map(async (index) => {
@@ -255,7 +255,7 @@ export class EdgeFeedReplicator extends Resource {
255
255
  }
256
256
 
257
257
  private async _integrateBlocks(feed: FeedWrapper<any>, blocks: FeedBlock[]) {
258
- log.info('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });
258
+ log('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });
259
259
 
260
260
  for (const block of blocks) {
261
261
  if (feed.has(block.index)) {
@@ -90,6 +90,7 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
90
90
 
91
91
  private _activeEdgePollingIntervalHandle: any | undefined = undefined;
92
92
  private readonly _activeEdgePollingInterval: number;
93
+ private _activeEdgePollingEnabled = false;
93
94
 
94
95
  @logInfo
95
96
  private readonly _spaceId: SpaceId;
@@ -106,18 +107,15 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
106
107
  }
107
108
 
108
109
  setActiveEdgePollingEnabled(enabled: boolean) {
109
- invariant(this.isOpen);
110
110
  const client = this._edgeClient;
111
111
  invariant(client);
112
- if (enabled && !this._activeEdgePollingIntervalHandle) {
113
- this._activeEdgePollingIntervalHandle = setInterval(() => {
114
- if (this._writer) {
115
- this._notarizePendingEdgeCredentials(client, this._writer);
116
- }
117
- }, this._activeEdgePollingInterval);
118
- } else if (!enabled && this._activeEdgePollingIntervalHandle) {
119
- clearInterval(this._activeEdgePollingIntervalHandle);
120
- this._activeEdgePollingIntervalHandle = undefined;
112
+ this._activeEdgePollingEnabled = enabled;
113
+ if (this.isOpen) {
114
+ if (enabled && !this._activeEdgePollingIntervalHandle) {
115
+ this._startPeriodicEdgePolling(client);
116
+ } else if (!enabled && this._activeEdgePollingIntervalHandle) {
117
+ this._stopPeriodicEdgePolling();
118
+ }
121
119
  }
122
120
  }
123
121
 
@@ -126,16 +124,18 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
126
124
  }
127
125
 
128
126
  protected override async _open() {
129
- if (this._edgeClient && this._writer) {
130
- this._notarizePendingEdgeCredentials(this._edgeClient, this._writer);
127
+ if (this._edgeClient) {
128
+ if (this._activeEdgePollingEnabled) {
129
+ this._startPeriodicEdgePolling(this._edgeClient);
130
+ }
131
+ if (this._writer) {
132
+ this._notarizePendingEdgeCredentials(this._edgeClient, this._writer);
133
+ }
131
134
  }
132
135
  }
133
136
 
134
137
  protected override async _close() {
135
- if (this._activeEdgePollingIntervalHandle) {
136
- clearInterval(this._activeEdgePollingIntervalHandle);
137
- this._activeEdgePollingIntervalHandle = undefined;
138
- }
138
+ this._stopPeriodicEdgePolling();
139
139
  await this._ctx.dispose();
140
140
  }
141
141
 
@@ -273,11 +273,26 @@ export class NotarizationPlugin extends Resource implements CredentialProcessor
273
273
  setWriter(writer: FeedWriter<Credential>) {
274
274
  invariant(!this._writer, 'Writer already set.');
275
275
  this._writer = writer;
276
- if (this._edgeClient) {
276
+ if (this._edgeClient && this.isOpen) {
277
277
  this._notarizePendingEdgeCredentials(this._edgeClient, writer);
278
278
  }
279
279
  }
280
280
 
281
+ private _startPeriodicEdgePolling(client: EdgeHttpClient) {
282
+ this._activeEdgePollingIntervalHandle = setInterval(() => {
283
+ if (this._writer) {
284
+ this._notarizePendingEdgeCredentials(client, this._writer);
285
+ }
286
+ }, this._activeEdgePollingInterval);
287
+ }
288
+
289
+ private _stopPeriodicEdgePolling() {
290
+ if (this._activeEdgePollingIntervalHandle) {
291
+ clearInterval(this._activeEdgePollingIntervalHandle);
292
+ this._activeEdgePollingIntervalHandle = undefined;
293
+ }
294
+ }
295
+
281
296
  /**
282
297
  * The method is used only for adding agent feeds to spaces.
283
298
  * When an agent is created we can admit them into all the existing spaces. In case the operation fails
@@ -3,8 +3,13 @@
3
3
  //
4
4
 
5
5
  import { EventSubscriptions, UpdateScheduler, scheduleTask } from '@dxos/async';
6
- import { Stream } from '@dxos/codec-protobuf';
7
- import { createAdmissionCredentials, type CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';
6
+ import { Stream } from '@dxos/codec-protobuf/stream';
7
+ import {
8
+ createAdmissionCredentials,
9
+ createDidFromIdentityKey,
10
+ type CredentialProcessor,
11
+ getCredentialAssertion,
12
+ } from '@dxos/credentials';
8
13
  import { raise } from '@dxos/debug';
9
14
  import { type SpaceManager } from '@dxos/echo-pipeline';
10
15
  import { writeMessages } from '@dxos/feed-store';
@@ -115,7 +120,9 @@ export class SpacesServiceImpl implements SpacesService {
115
120
  ctx,
116
121
  async () => {
117
122
  const dataSpaceManager = await this._getDataSpaceManager();
118
- const spaces = Array.from(dataSpaceManager.spaces.values()).map((space) => this._serializeSpace(space));
123
+ const spaces = await Promise.all(
124
+ Array.from(dataSpaceManager.spaces.values()).map((space) => this._serializeSpace(space)),
125
+ );
119
126
  log('update', () => ({ ids: spaces.map((space) => space.id) }));
120
127
  await this._updateMetrics();
121
128
  next({ spaces });
@@ -265,10 +272,10 @@ export class SpacesServiceImpl implements SpacesService {
265
272
  await myIdentity.controlPipeline.writer.write({ credential: { credential } });
266
273
  }
267
274
 
268
- return { space: this._serializeSpace(dataSpace) };
275
+ return { space: await this._serializeSpace(dataSpace) };
269
276
  }
270
277
 
271
- private _serializeSpace(space: DataSpace): Space {
278
+ private async _serializeSpace(space: DataSpace): Promise<Space> {
272
279
  return {
273
280
  id: space.id,
274
281
  spaceKey: space.key,
@@ -291,24 +298,27 @@ export class SpacesServiceImpl implements SpacesService {
291
298
 
292
299
  spaceRootUrl: space.databaseRoot?.url,
293
300
  },
294
- members: Array.from(space.inner.spaceState.members.values()).map((member) => {
295
- const peers = space.presence.getPeersOnline().filter(({ identityKey }) => identityKey.equals(member.key));
296
- const isMe = this._identityManager.identity?.identityKey.equals(member.key);
301
+ members: await Promise.all(
302
+ Array.from(space.inner.spaceState.members.values()).map(async (member) => {
303
+ const peers = space.presence.getPeersOnline().filter(({ identityKey }) => identityKey.equals(member.key));
304
+ const isMe = this._identityManager.identity?.identityKey.equals(member.key);
297
305
 
298
- if (isMe) {
299
- peers.push(space.presence.getLocalState());
300
- }
306
+ if (isMe) {
307
+ peers.push(space.presence.getLocalState());
308
+ }
301
309
 
302
- return {
303
- identity: {
304
- identityKey: member.key,
305
- profile: member.profile ?? {},
306
- },
307
- role: member.role,
308
- presence: peers.length > 0 ? SpaceMember.PresenceState.ONLINE : SpaceMember.PresenceState.OFFLINE,
309
- peerStates: peers,
310
- };
311
- }),
310
+ return {
311
+ identity: {
312
+ did: await createDidFromIdentityKey(member.key),
313
+ identityKey: member.key,
314
+ profile: member.profile ?? {},
315
+ },
316
+ role: member.role,
317
+ presence: peers.length > 0 ? SpaceMember.PresenceState.ONLINE : SpaceMember.PresenceState.OFFLINE,
318
+ peerStates: peers,
319
+ };
320
+ }),
321
+ ),
312
322
  creator: space.inner.spaceState.creator?.key,
313
323
  cache: space.cache,
314
324
  metrics: space.metrics,
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { type Event } from '@dxos/async';
6
- import { Stream } from '@dxos/codec-protobuf';
6
+ import { Stream } from '@dxos/codec-protobuf/stream';
7
7
  import { type Config } from '@dxos/config';
8
8
  import {
9
9
  GetDiagnosticsRequest,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const DXOS_VERSION = "0.7.5-main.9d26e3a";
1
+ export const DXOS_VERSION = "0.7.5-main.b19bfc8";