@dxos/client-services 0.7.4 → 0.7.5-labs.071a3e2

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 (96) hide show
  1. package/dist/lib/browser/{chunk-423GRVVV.mjs → chunk-SKOL3Q2R.mjs} +379 -267
  2. package/dist/lib/browser/chunk-SKOL3Q2R.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-ZS24HRVA.cjs → chunk-XTM3FUCM.cjs} +405 -293
  7. package/dist/lib/node/chunk-XTM3FUCM.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-OQOXRHWF.mjs → chunk-EQU6BG5J.mjs} +379 -267
  12. package/dist/lib/node-esm/chunk-EQU6BG5J.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-service.d.ts +1 -1
  17. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  18. package/dist/types/src/packlets/devices/devices-service.d.ts +1 -1
  19. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  20. package/dist/types/src/packlets/devtools/devtools.d.ts +1 -1
  21. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  22. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  23. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  24. package/dist/types/src/packlets/devtools/keys.d.ts +1 -1
  25. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  26. package/dist/types/src/packlets/devtools/metadata.d.ts +1 -1
  27. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  28. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  29. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  30. package/dist/types/src/packlets/devtools/spaces.d.ts +1 -1
  31. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  32. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  33. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  34. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  35. package/dist/types/src/packlets/identity/identity-manager.d.ts +0 -3
  36. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  37. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +12 -4
  38. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  39. package/dist/types/src/packlets/identity/identity-service.d.ts +9 -4
  40. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  41. package/dist/types/src/packlets/identity/identity.d.ts +3 -1
  42. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  43. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  44. package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
  45. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  47. package/dist/types/src/packlets/invitations/utils.d.ts +1 -0
  48. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  49. package/dist/types/src/packlets/logging/logging-service.d.ts +1 -1
  50. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  51. package/dist/types/src/packlets/network/network-service.d.ts +9 -2
  52. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  53. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  54. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  55. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +3 -0
  56. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  57. package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
  58. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  59. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  60. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  61. package/dist/types/src/version.d.ts +1 -1
  62. package/dist/types/src/version.d.ts.map +1 -1
  63. package/dist/types/tsconfig.tsbuildinfo +1 -0
  64. package/package.json +38 -38
  65. package/src/packlets/agents/edge-agent-service.ts +1 -1
  66. package/src/packlets/devices/devices-service.ts +1 -1
  67. package/src/packlets/devtools/devtools.ts +1 -1
  68. package/src/packlets/devtools/feeds.ts +1 -1
  69. package/src/packlets/devtools/keys.ts +1 -1
  70. package/src/packlets/devtools/metadata.ts +1 -1
  71. package/src/packlets/devtools/network.ts +1 -1
  72. package/src/packlets/devtools/spaces.ts +1 -1
  73. package/src/packlets/diagnostics/diagnostics.ts +17 -13
  74. package/src/packlets/identity/contacts-service.ts +1 -1
  75. package/src/packlets/identity/identity-manager.ts +3 -29
  76. package/src/packlets/identity/identity-recovery-manager.ts +86 -9
  77. package/src/packlets/identity/identity-service.ts +17 -4
  78. package/src/packlets/identity/identity.test.ts +2 -1
  79. package/src/packlets/identity/identity.ts +4 -1
  80. package/src/packlets/invitations/invitations-handler.ts +15 -6
  81. package/src/packlets/invitations/invitations-manager.ts +1 -1
  82. package/src/packlets/invitations/invitations-service.ts +1 -1
  83. package/src/packlets/invitations/space-invitation-protocol.ts +2 -3
  84. package/src/packlets/invitations/utils.ts +7 -0
  85. package/src/packlets/logging/logging-service.ts +1 -1
  86. package/src/packlets/network/network-service.ts +39 -1
  87. package/src/packlets/services/service-context.ts +3 -1
  88. package/src/packlets/spaces/data-space-manager.ts +1 -1
  89. package/src/packlets/spaces/edge-feed-replicator.ts +16 -10
  90. package/src/packlets/spaces/notarization-plugin.ts +32 -17
  91. package/src/packlets/spaces/spaces-service.ts +31 -21
  92. package/src/packlets/system/system-service.ts +1 -1
  93. package/src/version.ts +1 -5
  94. package/dist/lib/browser/chunk-423GRVVV.mjs.map +0 -7
  95. package/dist/lib/node/chunk-ZS24HRVA.cjs.map +0 -7
  96. package/dist/lib/node-esm/chunk-OQOXRHWF.mjs.map +0 -7
@@ -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();
@@ -380,10 +381,11 @@ export class ServiceContext extends Resource {
380
381
  let edgeIdentity: EdgeIdentity;
381
382
  const identity = this.identityManager.identity;
382
383
  if (identity) {
383
- log.info('Setting identity on edge connection', {
384
+ log('setting identity on edge connection', {
384
385
  identity: identity.identityKey.toHex(),
385
386
  swarms: this.networkManager.topics,
386
387
  });
388
+
387
389
  if (params?.deviceCredential) {
388
390
  edgeIdentity = await createChainEdgeIdentity(
389
391
  identity.signer,
@@ -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,
@@ -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,13 +143,16 @@ 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
- const logPayload =
151
- message.type === 'data' ? { feedKey: message.feedKey, blocks: message.blocks.map((b) => b.index) } : { message };
152
- log.info('sending message', logPayload);
150
+ if (message.type === 'data') {
151
+ log('sending blocks', {
152
+ feedKey: message.feedKey,
153
+ blocks: message.blocks.map((b) => b.index),
154
+ });
155
+ }
153
156
 
154
157
  invariant(message.feedKey);
155
158
  const payloadValue = bufferToArray(encodeCbor(message));
@@ -175,8 +178,6 @@ export class EdgeFeedReplicator extends Resource {
175
178
  scheduleMicroTask(this._connectionCtx, async () => {
176
179
  switch (message.type) {
177
180
  case 'metadata': {
178
- log.info('received metadata', { message });
179
-
180
181
  const feedKey = PublicKey.fromHex(message.feedKey);
181
182
  const feed = this._feeds.get(feedKey);
182
183
  if (!feed) {
@@ -188,13 +189,18 @@ export class EdgeFeedReplicator extends Resource {
188
189
 
189
190
  this._remoteLength.set(feedKey, message.length);
190
191
 
192
+ const logMeta = { localLength: feed.length, remoteLength: message.length, feedKey };
191
193
  if (message.length > feed.length) {
194
+ log('requesting missing blocks', logMeta);
195
+
192
196
  await this._sendMessage({
193
197
  type: 'request',
194
198
  feedKey: feedKey.toHex(),
195
199
  range: { from: feed.length, to: message.length },
196
200
  });
197
201
  } else if (message.length < feed.length) {
202
+ log('pushing blocks to remote', logMeta);
203
+
198
204
  await this._pushBlocks(feed, message.length, feed.length);
199
205
  }
200
206
 
@@ -202,7 +208,7 @@ export class EdgeFeedReplicator extends Resource {
202
208
  }
203
209
 
204
210
  case 'data': {
205
- 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) });
206
212
 
207
213
  const feedKey = PublicKey.fromHex(message.feedKey);
208
214
  const feed = this._feeds.get(feedKey);
@@ -223,7 +229,7 @@ export class EdgeFeedReplicator extends Resource {
223
229
  }
224
230
 
225
231
  private async _pushBlocks(feed: FeedWrapper<any>, from: number, to: number) {
226
- log.info('pushing blocks', { feed: feed.key.toHex(), from, to });
232
+ log('pushing blocks', { feed: feed.key.toHex(), from, to });
227
233
 
228
234
  const blocks: FeedBlock[] = await Promise.all(
229
235
  rangeFromTo(from, to).map(async (index) => {
@@ -249,7 +255,7 @@ export class EdgeFeedReplicator extends Resource {
249
255
  }
250
256
 
251
257
  private async _integrateBlocks(feed: FeedWrapper<any>, blocks: FeedBlock[]) {
252
- log.info('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });
258
+ log('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });
253
259
 
254
260
  for (const block of blocks) {
255
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,5 +1 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- export const DXOS_VERSION = '0.7.4'; // {x-release-please-version}
1
+ export const DXOS_VERSION = "0.7.5-labs.071a3e2";