@dxos/client-services 0.8.1 → 0.8.2-main.10c050d

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 (134) hide show
  1. package/dist/lib/browser/{chunk-MHDASPY5.mjs → chunk-LY3V7LMQ.mjs} +535 -551
  2. package/dist/lib/browser/chunk-LY3V7LMQ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +1 -1
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/{chunk-A2WCOW6P.cjs → chunk-LYHT7662.cjs} +704 -709
  9. package/dist/lib/node/chunk-LYHT7662.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +47 -47
  11. package/dist/lib/node/index.cjs.map +3 -3
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +8 -8
  14. package/dist/lib/node/testing/index.cjs.map +3 -3
  15. package/dist/lib/node-esm/{chunk-SK52YZK7.mjs → chunk-LLRVFL7L.mjs} +535 -540
  16. package/dist/lib/node-esm/chunk-LLRVFL7L.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +1 -1
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/meta.json +1 -1
  20. package/dist/lib/node-esm/testing/index.mjs +1 -1
  21. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  22. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  23. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
  24. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  25. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  26. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  27. package/dist/types/src/packlets/devtools/keys.d.ts.map +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.map +1 -1
  30. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  31. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  32. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  33. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  34. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  35. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +1 -1
  36. package/dist/types/src/packlets/identity/identity-manager.d.ts +2 -2
  37. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  38. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +1 -1
  39. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  40. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  41. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  42. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  43. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  44. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  45. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  46. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  47. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  48. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  49. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -1
  50. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  51. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  52. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  53. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  54. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  55. package/dist/types/src/packlets/network/network-service.d.ts +3 -1
  56. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  57. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  58. package/dist/types/src/packlets/services/service-context.d.ts +1 -0
  59. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  60. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  61. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  62. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  63. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +1 -1
  64. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  65. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  66. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  67. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +1 -1
  68. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  69. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  70. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  71. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  72. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  73. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  74. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  75. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  76. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  77. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  78. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  79. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  80. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  81. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  82. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  83. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  84. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  85. package/dist/types/src/version.d.ts +1 -1
  86. package/dist/types/src/version.d.ts.map +1 -1
  87. package/dist/types/tsconfig.tsbuildinfo +1 -1
  88. package/package.json +39 -38
  89. package/src/packlets/agents/edge-agent-manager.ts +6 -6
  90. package/src/packlets/agents/edge-agent-service.ts +8 -11
  91. package/src/packlets/devices/devices-service.ts +5 -3
  92. package/src/packlets/identity/authenticator.ts +2 -2
  93. package/src/packlets/identity/default-space-state-machine.ts +1 -1
  94. package/src/packlets/identity/identity-manager.ts +13 -9
  95. package/src/packlets/identity/identity-recovery-manager.ts +6 -4
  96. package/src/packlets/identity/identity-service.ts +4 -4
  97. package/src/packlets/identity/identity.test.ts +9 -6
  98. package/src/packlets/identity/identity.ts +5 -5
  99. package/src/packlets/invitations/device-invitation-protocol.ts +1 -1
  100. package/src/packlets/invitations/edge-invitation-handler.ts +3 -3
  101. package/src/packlets/invitations/invitation-guest-extenstion.ts +3 -3
  102. package/src/packlets/invitations/invitation-host-extension.ts +5 -5
  103. package/src/packlets/invitations/invitation-topology.ts +1 -1
  104. package/src/packlets/invitations/invitations-handler.ts +2 -2
  105. package/src/packlets/invitations/invitations-manager.ts +15 -4
  106. package/src/packlets/invitations/space-invitation-protocol.ts +1 -1
  107. package/src/packlets/locks/browser.ts +4 -4
  108. package/src/packlets/locks/node.ts +2 -2
  109. package/src/packlets/logging/logging-service.ts +2 -2
  110. package/src/packlets/network/network-service.ts +11 -17
  111. package/src/packlets/services/client-rpc-server.ts +2 -2
  112. package/src/packlets/services/service-context.ts +10 -6
  113. package/src/packlets/services/service-host.ts +13 -5
  114. package/src/packlets/services/service-registry.ts +3 -3
  115. package/src/packlets/space-export/space-archive-reader.ts +2 -1
  116. package/src/packlets/space-export/space-archive-writer.ts +3 -3
  117. package/src/packlets/spaces/automerge-space-state.ts +3 -3
  118. package/src/packlets/spaces/data-space-manager.ts +47 -41
  119. package/src/packlets/spaces/data-space.ts +27 -20
  120. package/src/packlets/spaces/edge-feed-replicator.test.ts +2 -1
  121. package/src/packlets/spaces/edge-feed-replicator.ts +14 -13
  122. package/src/packlets/spaces/epoch-migrations.ts +3 -2
  123. package/src/packlets/spaces/notarization-plugin.test.ts +1 -1
  124. package/src/packlets/spaces/notarization-plugin.ts +18 -18
  125. package/src/packlets/spaces/spaces-service.ts +7 -6
  126. package/src/packlets/storage/profile-archive.ts +2 -1
  127. package/src/packlets/system/system-service.ts +2 -2
  128. package/src/packlets/testing/test-builder.ts +3 -3
  129. package/src/packlets/worker/worker-runtime.ts +4 -4
  130. package/src/packlets/worker/worker-session.ts +3 -3
  131. package/src/version.ts +1 -5
  132. package/dist/lib/browser/chunk-MHDASPY5.mjs.map +0 -7
  133. package/dist/lib/node/chunk-A2WCOW6P.cjs.map +0 -7
  134. package/dist/lib/node-esm/chunk-SK52YZK7.mjs.map +0 -7
@@ -25,7 +25,7 @@ export class AutomergeSpaceState extends Resource implements CredentialProcessor
25
25
  this._isProcessingRootDocs = false;
26
26
  }
27
27
 
28
- async processCredential(credential: Credential) {
28
+ async processCredential(credential: Credential): Promise<void> {
29
29
  if (!checkCredentialType(credential, 'dxos.halo.credentials.Epoch')) {
30
30
  return;
31
31
  }
@@ -42,7 +42,7 @@ export class AutomergeSpaceState extends Resource implements CredentialProcessor
42
42
  this.onNewEpoch.emit(credential);
43
43
  }
44
44
 
45
- startProcessingRootDocs() {
45
+ startProcessingRootDocs(): void {
46
46
  if (this._isProcessingRootDocs) {
47
47
  return;
48
48
  }
@@ -53,7 +53,7 @@ export class AutomergeSpaceState extends Resource implements CredentialProcessor
53
53
  this._isProcessingRootDocs = true;
54
54
  }
55
55
 
56
- async ensureEpochInitialized() {
56
+ async ensureEpochInitialized(): Promise<void> {
57
57
  await this.onNewEpoch.waitForCondition(() => !!this.lastEpoch);
58
58
  }
59
59
  }
@@ -2,14 +2,10 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import { type Doc } from '@automerge/automerge';
6
+ import { interpretAsDocumentId, type AutomergeUrl, type DocHandle, type DocumentId } from '@automerge/automerge-repo';
7
+
5
8
  import { Event, synchronized, trackLeaks } from '@dxos/async';
6
- import { type Doc } from '@dxos/automerge/automerge';
7
- import {
8
- interpretAsDocumentId,
9
- type AutomergeUrl,
10
- type DocHandle,
11
- type DocumentId,
12
- } from '@dxos/automerge/automerge-repo';
13
9
  import { PropertiesType, TYPE_PROPERTIES } from '@dxos/client-protocol';
14
10
  import { Context, LifecycleState, Resource, cancelWithContext } from '@dxos/context';
15
11
  import {
@@ -32,15 +28,16 @@ import {
32
28
  type SpaceManager,
33
29
  type SpaceProtocol,
34
30
  type SpaceProtocolSession,
31
+ FIND_PARAMS,
35
32
  } from '@dxos/echo-pipeline';
36
33
  import {
37
34
  SpaceDocVersion,
38
35
  createIdFromSpaceKey,
39
36
  encodeReference,
40
37
  type ObjectStructure,
41
- type SpaceDoc,
38
+ type DatabaseDirectory,
42
39
  } from '@dxos/echo-protocol';
43
- import { createObjectId, getTypeReference } from '@dxos/echo-schema';
40
+ import { ObjectId, getTypeReference } from '@dxos/echo-schema';
44
41
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
45
42
  import { writeMessages, type FeedStore } from '@dxos/feed-store';
46
43
  import { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';
@@ -177,24 +174,29 @@ export class DataSpaceManager extends Resource {
177
174
  id: 'spaces',
178
175
  name: 'Spaces',
179
176
  fetch: async () => {
180
- return Array.from(this._spaces.values()).map((space) => {
181
- const rootUrl = space.automergeSpaceState.rootUrl;
182
- const rootHandle = rootUrl ? this._echoHost.automergeRepo.find(rootUrl as AutomergeUrl) : undefined;
183
- const rootDoc = rootHandle?.docSync() as Doc<SpaceDoc> | undefined;
184
-
185
- const properties = rootDoc && findInlineObjectOfType(rootDoc, TYPE_PROPERTIES);
186
-
187
- return {
188
- key: space.key.toHex(),
189
- state: SpaceState[space.state],
190
- name: properties?.[1].data.name ?? null,
191
- inlineObjects: rootDoc ? Object.keys(rootDoc.objects ?? {}).length : null,
192
- linkedObjects: rootDoc ? Object.keys(rootDoc.links ?? {}).length : null,
193
- credentials: space.inner.spaceState.credentials.length,
194
- members: space.inner.spaceState.members.size,
195
- rootUrl,
196
- };
197
- });
177
+ return Promise.all(
178
+ Array.from(this._spaces.values()).map(async (space) => {
179
+ const rootUrl = space.automergeSpaceState.rootUrl;
180
+ const rootHandle = rootUrl
181
+ ? await this._echoHost.automergeRepo.find<Doc<DatabaseDirectory>>(rootUrl as AutomergeUrl, FIND_PARAMS)
182
+ : undefined;
183
+ await rootHandle?.whenReady();
184
+ const rootDoc = rootHandle?.doc();
185
+
186
+ const properties = rootDoc && findInlineObjectOfType(rootDoc, TYPE_PROPERTIES);
187
+
188
+ return {
189
+ key: space.key.toHex(),
190
+ state: SpaceState[space.state],
191
+ name: properties?.[1].data.name ?? null,
192
+ inlineObjects: rootDoc ? Object.keys(rootDoc.objects ?? {}).length : null,
193
+ linkedObjects: rootDoc ? Object.keys(rootDoc.links ?? {}).length : null,
194
+ credentials: space.inner.spaceState.credentials.length,
195
+ members: space.inner.spaceState.members.size,
196
+ rootUrl,
197
+ };
198
+ }),
199
+ );
198
200
  },
199
201
  });
200
202
  }
@@ -209,7 +211,7 @@ export class DataSpaceManager extends Resource {
209
211
  }
210
212
 
211
213
  @synchronized
212
- protected override async _open() {
214
+ protected override async _open(): Promise<void> {
213
215
  log('open');
214
216
  log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
215
217
  log('metadata loaded', { spaces: this._metadataStore.spaces.length });
@@ -229,7 +231,7 @@ export class DataSpaceManager extends Resource {
229
231
  }
230
232
 
231
233
  @synchronized
232
- protected override async _close() {
234
+ protected override async _close(): Promise<void> {
233
235
  log('close');
234
236
  for (const space of this._spaces.values()) {
235
237
  await space.close();
@@ -241,7 +243,7 @@ export class DataSpaceManager extends Resource {
241
243
  * Creates a new space writing the genesis credentials to the control feed.
242
244
  */
243
245
  @synchronized
244
- async createSpace(options: CreateSpaceOptions = {}) {
246
+ async createSpace(options: CreateSpaceOptions = {}): Promise<DataSpace> {
245
247
  assertArgument(!!options.rootUrl === !!options.documents, 'root url must be required when providing documents');
246
248
 
247
249
  assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
@@ -283,7 +285,7 @@ export class DataSpaceManager extends Resource {
283
285
  let root: DatabaseRoot;
284
286
  if (options.rootUrl) {
285
287
  const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
286
- const rootDocHandle = await this._echoHost.loadDoc<SpaceDoc>(Context.default(), newRootDocId);
288
+ const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(Context.default(), newRootDocId);
287
289
  DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
288
290
 
289
291
  root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
@@ -319,7 +321,11 @@ export class DataSpaceManager extends Resource {
319
321
  }
320
322
  switch (space.databaseRoot.getVersion()) {
321
323
  case SpaceDocVersion.CURRENT: {
322
- const [_, properties] = findInlineObjectOfType(space.databaseRoot.docSync()!, TYPE_PROPERTIES) ?? [];
324
+ if (!space.databaseRoot.handle.isReady()) {
325
+ log.warn('waiting for space root to be ready', { spaceId: space.id });
326
+ await space.databaseRoot.handle.whenReady();
327
+ }
328
+ const [_, properties] = findInlineObjectOfType(space.databaseRoot.doc()!, TYPE_PROPERTIES) ?? [];
323
329
  return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
324
330
  }
325
331
  case SpaceDocVersion.LEGACY: {
@@ -332,7 +338,7 @@ export class DataSpaceManager extends Resource {
332
338
  }
333
339
  }
334
340
 
335
- async createDefaultSpace() {
341
+ async createDefaultSpace(): Promise<DataSpace> {
336
342
  const space = await this.createSpace();
337
343
  const document = await this._getSpaceRootDocument(space);
338
344
 
@@ -349,8 +355,8 @@ export class DataSpaceManager extends Resource {
349
355
  },
350
356
  };
351
357
 
352
- const propertiesId = createObjectId();
353
- document.change((doc: SpaceDoc) => {
358
+ const propertiesId = ObjectId.random();
359
+ document.change((doc: DatabaseDirectory) => {
354
360
  setDeep(doc, ['objects', propertiesId], properties);
355
361
  });
356
362
 
@@ -358,10 +364,10 @@ export class DataSpaceManager extends Resource {
358
364
  return space;
359
365
  }
360
366
 
361
- private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<SpaceDoc>> {
367
+ private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
362
368
  const automergeIndex = space.automergeSpaceState.rootUrl;
363
369
  invariant(automergeIndex);
364
- const document = this._echoHost.automergeRepo.find<SpaceDoc>(automergeIndex as any);
370
+ const document = await this._echoHost.automergeRepo.find<DatabaseDirectory>(automergeIndex as any, FIND_PARAMS);
365
371
  await document.whenReady();
366
372
  return document;
367
373
  }
@@ -423,7 +429,7 @@ export class DataSpaceManager extends Resource {
423
429
  * Used by invitation handler.
424
430
  * TODO(dmaretskyi): Consider removing.
425
431
  */
426
- async waitUntilSpaceReady(spaceKey: PublicKey) {
432
+ async waitUntilSpaceReady(spaceKey: PublicKey): Promise<void> {
427
433
  await cancelWithContext(
428
434
  this._ctx,
429
435
  this.updated.waitForCondition(() => {
@@ -447,7 +453,7 @@ export class DataSpaceManager extends Resource {
447
453
  });
448
454
  }
449
455
 
450
- async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting) {
456
+ async setSpaceEdgeReplicationSetting(spaceKey: PublicKey, setting: EdgeReplicationSetting): Promise<void> {
451
457
  const space = this._spaces.get(spaceKey);
452
458
  invariant(space, 'Space not found.');
453
459
 
@@ -467,7 +473,7 @@ export class DataSpaceManager extends Resource {
467
473
  space.stateUpdate.emit();
468
474
  }
469
475
 
470
- private async _constructSpace(metadata: SpaceMetadata) {
476
+ private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
471
477
  log('construct space', { metadata });
472
478
  const gossip = new Gossip({
473
479
  localPeerId: this._signingContext.deviceKey,
@@ -591,7 +597,7 @@ export class DataSpaceManager extends Resource {
591
597
  return dataSpace;
592
598
  }
593
599
 
594
- private async _connectEchoMeshReplicator(space: Space, session: Teleport) {
600
+ private async _connectEchoMeshReplicator(space: Space, session: Teleport): Promise<void> {
595
601
  const replicator = this._meshReplicator;
596
602
  if (!replicator) {
597
603
  log.warn('p2p automerge replication disabled', { space: space.key });
@@ -2,8 +2,10 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import { save } from '@automerge/automerge';
6
+ import { type DocHandle } from '@automerge/automerge-repo';
7
+
5
8
  import { Event, Mutex, scheduleTask, sleep, synchronized, trackLeaks } from '@dxos/async';
6
- import { save } from '@dxos/automerge/automerge';
7
9
  import { AUTH_TIMEOUT } from '@dxos/client-protocol';
8
10
  import { Context, ContextDisposedError, cancelWithContext } from '@dxos/context';
9
11
  import type { SpecificCredential } from '@dxos/credentials';
@@ -14,8 +16,9 @@ import {
14
16
  createMappedFeedWriter,
15
17
  type MetadataStore,
16
18
  type Space,
19
+ FIND_PARAMS,
17
20
  } from '@dxos/echo-pipeline';
18
- import { SpaceDocVersion, type SpaceDoc } from '@dxos/echo-protocol';
21
+ import { SpaceDocVersion, type DatabaseDirectory } from '@dxos/echo-protocol';
19
22
  import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
20
23
  import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
21
24
  import { failedInvariant, invariant } from '@dxos/invariant';
@@ -226,13 +229,13 @@ export class DataSpace {
226
229
  }
227
230
 
228
231
  @synchronized
229
- async open() {
232
+ async open(): Promise<void> {
230
233
  if (this._state === SpaceState.SPACE_CLOSED) {
231
234
  await this._open();
232
235
  }
233
236
  }
234
237
 
235
- private async _open() {
238
+ private async _open(): Promise<void> {
236
239
  await this._presence.open();
237
240
  await this._gossip.open();
238
241
  await this._notarizationPlugin.open();
@@ -259,11 +262,11 @@ export class DataSpace {
259
262
  }
260
263
 
261
264
  @synchronized
262
- async close() {
265
+ async close(): Promise<void> {
263
266
  await this._close();
264
267
  }
265
268
 
266
- private async _close() {
269
+ private async _close(): Promise<void> {
267
270
  await this._callbacks.beforeClose?.();
268
271
 
269
272
  await this.preClose.callSerial();
@@ -291,18 +294,18 @@ export class DataSpace {
291
294
  await this._gossip.close();
292
295
  }
293
296
 
294
- async postMessage(channel: string, message: any) {
297
+ async postMessage(channel: string, message: any): Promise<void> {
295
298
  return this._gossip.postMessage(channel, message);
296
299
  }
297
300
 
298
- listen(channel: string, callback: (message: GossipMessage) => void) {
301
+ listen(channel: string, callback: (message: GossipMessage) => void): { unsubscribe: () => void } {
299
302
  return this._gossip.listen(channel, callback);
300
303
  }
301
304
 
302
305
  /**
303
306
  * Initialize the data pipeline in a separate task.
304
307
  */
305
- initializeDataPipelineAsync() {
308
+ initializeDataPipelineAsync(): void {
306
309
  scheduleTask(this._ctx, async () => {
307
310
  try {
308
311
  this.metrics.pipelineInitBegin = new Date();
@@ -325,7 +328,7 @@ export class DataSpace {
325
328
  }
326
329
 
327
330
  @trace.span({ showInBrowserTimeline: true })
328
- async initializeDataPipeline() {
331
+ async initializeDataPipeline(): Promise<void> {
329
332
  if (this._state !== SpaceState.SPACE_CONTROL_ONLY) {
330
333
  throw new SystemError('Invalid operation');
331
334
  }
@@ -352,7 +355,7 @@ export class DataSpace {
352
355
 
353
356
  async *getAllDocuments(): AsyncIterable<[string, Uint8Array]> {
354
357
  invariant(this._databaseRoot, 'Space is not ready');
355
- const doc = this._databaseRoot.docSync() ?? failedInvariant();
358
+ const doc = this._databaseRoot.doc() ?? failedInvariant();
356
359
  const root = save(doc);
357
360
  yield [this._databaseRoot.documentId, root];
358
361
 
@@ -362,7 +365,7 @@ export class DataSpace {
362
365
  }
363
366
  }
364
367
 
365
- private async _enterReadyState() {
368
+ private async _enterReadyState(): Promise<void> {
366
369
  await this._callbacks.beforeReady?.();
367
370
 
368
371
  this._state = SpaceState.SPACE_READY;
@@ -373,7 +376,7 @@ export class DataSpace {
373
376
  }
374
377
 
375
378
  @trace.span({ showInBrowserTimeline: true })
376
- private async _initializeAndReadControlPipeline() {
379
+ private async _initializeAndReadControlPipeline(): Promise<void> {
377
380
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
378
381
  ctx: this._ctx,
379
382
  timeout: 10_000,
@@ -399,7 +402,7 @@ export class DataSpace {
399
402
  }
400
403
 
401
404
  @timed(10_000)
402
- private async _createWritableFeeds() {
405
+ private async _createWritableFeeds(): Promise<void> {
403
406
  const credentials: Credential[] = [];
404
407
  if (!this.inner.controlFeedKey) {
405
408
  const controlFeed = await this._feedStore.openFeed(await this._keyring.createKey(), { writable: true });
@@ -456,15 +459,19 @@ export class DataSpace {
456
459
  }
457
460
  }
458
461
 
459
- private _onNewAutomergeRoot(rootUrl: string) {
462
+ private _onNewAutomergeRoot(rootUrl: string): void {
460
463
  log('loading automerge root doc for space', { space: this.key, rootUrl });
461
464
 
462
- const handle = this._echoHost.automergeRepo.find<SpaceDoc>(rootUrl as any);
465
+ let handle: DocHandle<DatabaseDirectory>;
463
466
 
464
467
  // TODO(dmaretskyi): Make this single-threaded (but doc loading should still be parallel to not block epoch processing).
465
468
  queueMicrotask(async () => {
466
469
  try {
467
470
  await warnAfterTimeout(5_000, 'Automerge root doc load timeout (DataSpace)', async () => {
471
+ handle = await cancelWithContext(
472
+ this._ctx,
473
+ this._echoHost.automergeRepo.find<DatabaseDirectory>(rootUrl as any, FIND_PARAMS),
474
+ );
468
475
  await cancelWithContext(this._ctx, handle.whenReady());
469
476
  });
470
477
  if (this._ctx.disposed) {
@@ -475,7 +482,7 @@ export class DataSpace {
475
482
  using _guard = await this._epochProcessingMutex.acquire();
476
483
 
477
484
  // Attaching space keys to legacy documents.
478
- const doc = handle.docSync() ?? failedInvariant();
485
+ const doc = handle.doc() ?? failedInvariant();
479
486
  if (!doc.access?.spaceKey) {
480
487
  handle.change((doc: any) => {
481
488
  doc.access = { spaceKey: this.key.toHex() };
@@ -506,7 +513,7 @@ export class DataSpace {
506
513
  }
507
514
 
508
515
  // TODO(dmaretskyi): Use profile from signing context.
509
- async updateOwnProfile(profile: ProfileDocument) {
516
+ async updateOwnProfile(profile: ProfileDocument): Promise<void> {
510
517
  const credential = await this._signingContext.credentialSigner.createCredential({
511
518
  subject: this._signingContext.identityKey,
512
519
  assertion: {
@@ -561,7 +568,7 @@ export class DataSpace {
561
568
  }
562
569
 
563
570
  @synchronized
564
- async activate() {
571
+ async activate(): Promise<void> {
565
572
  if (![SpaceState.SPACE_CLOSED, SpaceState.SPACE_INACTIVE].includes(this._state)) {
566
573
  return;
567
574
  }
@@ -572,7 +579,7 @@ export class DataSpace {
572
579
  }
573
580
 
574
581
  @synchronized
575
- async deactivate() {
582
+ async deactivate(): Promise<void> {
576
583
  if (this._state === SpaceState.SPACE_INACTIVE) {
577
584
  return;
578
585
  }
@@ -14,6 +14,7 @@ import { createTestEdgeWsServer } from '@dxos/edge-client/testing';
14
14
  import { FeedFactory, FeedStore, type FeedWrapper } from '@dxos/feed-store';
15
15
  import { Keyring } from '@dxos/keyring';
16
16
  import { SpaceId } from '@dxos/keys';
17
+ import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
17
18
  import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
18
19
  import { createStorage } from '@dxos/random-access-storage';
19
20
  import { openAndClose } from '@dxos/test-utils';
@@ -44,7 +45,7 @@ describe('EdgeFeedReplicator', () => {
44
45
  const { endpoint, admitConnection, messageSink } = await createEdge();
45
46
  const { messenger } = await createClient(endpoint);
46
47
  admitConnection.wake();
47
- await expect.poll(() => messenger.isConnected).toBeTruthy();
48
+ await expect.poll(() => messenger.status).toBe(EdgeStatus.CONNECTED);
48
49
 
49
50
  await attachReplicator(messenger);
50
51
  await expect.poll(() => messageSink.length).toEqual(1);
@@ -19,6 +19,7 @@ import {
19
19
  type Message as RouterMessage,
20
20
  } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
21
21
  import type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';
22
+ import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
22
23
  import { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';
23
24
 
24
25
  export type EdgeFeedReplicatorParams = {
@@ -84,9 +85,9 @@ export class EdgeFeedReplicator extends Resource {
84
85
  );
85
86
  }
86
87
 
87
- private async _handleReconnect() {
88
+ private async _handleReconnect(): Promise<void> {
88
89
  await this._resetConnection();
89
- if (this._messenger.isConnected) {
90
+ if (this._messenger.status === EdgeStatus.CONNECTED) {
90
91
  this._startReplication();
91
92
  }
92
93
  }
@@ -96,7 +97,7 @@ export class EdgeFeedReplicator extends Resource {
96
97
  await this._resetConnection();
97
98
  }
98
99
 
99
- private _startReplication() {
100
+ private _startReplication(): void {
100
101
  this._connected = true;
101
102
  const connectionCtx = this._createConnectionContext();
102
103
  this._connectionCtx = connectionCtx;
@@ -108,7 +109,7 @@ export class EdgeFeedReplicator extends Resource {
108
109
  });
109
110
  }
110
111
 
111
- private async _resetConnection() {
112
+ private async _resetConnection(): Promise<void> {
112
113
  log('resetConnection');
113
114
  this._connected = false;
114
115
  await this._connectionCtx?.dispose();
@@ -116,7 +117,7 @@ export class EdgeFeedReplicator extends Resource {
116
117
  this._remoteLength.clear();
117
118
  }
118
119
 
119
- async addFeed(feed: FeedWrapper<any>) {
120
+ async addFeed(feed: FeedWrapper<any>): Promise<void> {
120
121
  log('addFeed', { key: feed.key, connected: this._connected, hasConnectionCtx: !!this._connectionCtx });
121
122
  this._feeds.set(feed.key, feed);
122
123
 
@@ -125,11 +126,11 @@ export class EdgeFeedReplicator extends Resource {
125
126
  }
126
127
  }
127
128
 
128
- private _getPushMutex(key: PublicKey) {
129
+ private _getPushMutex(key: PublicKey): Mutex {
129
130
  return defaultMap(this._pushMutex, key, () => new Mutex());
130
131
  }
131
132
 
132
- private async _replicateFeed(ctx: Context, feed: FeedWrapper<any>) {
133
+ private async _replicateFeed(ctx: Context, feed: FeedWrapper<any>): Promise<void> {
133
134
  log('replicateFeed', { key: feed.key });
134
135
  await this._sendMessage({
135
136
  type: 'get-metadata',
@@ -141,7 +142,7 @@ export class EdgeFeedReplicator extends Resource {
141
142
  });
142
143
  }
143
144
 
144
- private async _sendMessage(message: ProtocolMessage) {
145
+ private async _sendMessage(message: ProtocolMessage): Promise<void> {
145
146
  if (!this._connectionCtx) {
146
147
  log('message dropped because connection was disposed');
147
148
  return;
@@ -170,7 +171,7 @@ export class EdgeFeedReplicator extends Resource {
170
171
  );
171
172
  }
172
173
 
173
- private _onMessage(message: ProtocolMessage) {
174
+ private _onMessage(message: ProtocolMessage): void {
174
175
  if (!this._connectionCtx) {
175
176
  log.warn('received message after connection context was disposed');
176
177
  return;
@@ -228,7 +229,7 @@ export class EdgeFeedReplicator extends Resource {
228
229
  });
229
230
  }
230
231
 
231
- private async _pushBlocks(feed: FeedWrapper<any>, from: number, to: number) {
232
+ private async _pushBlocks(feed: FeedWrapper<any>, from: number, to: number): Promise<void> {
232
233
  log('pushing blocks', { feed: feed.key.toHex(), from, to });
233
234
 
234
235
  const blocks: FeedBlock[] = await Promise.all(
@@ -254,7 +255,7 @@ export class EdgeFeedReplicator extends Resource {
254
255
  this._remoteLength.set(feed.key, to);
255
256
  }
256
257
 
257
- private async _integrateBlocks(feed: FeedWrapper<any>, blocks: FeedBlock[]) {
258
+ private async _integrateBlocks(feed: FeedWrapper<any>, blocks: FeedBlock[]): Promise<void> {
258
259
  log('integrating blocks', { feed: feed.key.toHex(), blocks: blocks.length });
259
260
 
260
261
  for (const block of blocks) {
@@ -272,7 +273,7 @@ export class EdgeFeedReplicator extends Resource {
272
273
  }
273
274
  }
274
275
 
275
- private async _pushBlocksIfNeeded(feed: FeedWrapper<any>) {
276
+ private async _pushBlocksIfNeeded(feed: FeedWrapper<any>): Promise<void> {
276
277
  using _ = await this._getPushMutex(feed.key).acquire();
277
278
 
278
279
  if (!this._remoteLength.has(feed.key)) {
@@ -286,7 +287,7 @@ export class EdgeFeedReplicator extends Resource {
286
287
  }
287
288
  }
288
289
 
289
- private _createConnectionContext() {
290
+ private _createConnectionContext(): Context {
290
291
  const connectionCtx = new Context({
291
292
  onError: async (err: any) => {
292
293
  if (connectionCtx !== this._connectionCtx) {
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import type { AutomergeUrl } from '@dxos/automerge/automerge-repo';
5
+ import type { AutomergeUrl } from '@automerge/automerge-repo';
6
+
6
7
  import { type Context } from '@dxos/context';
7
8
  import { type EchoHost } from '@dxos/echo-pipeline';
8
9
  import { invariant } from '@dxos/invariant';
@@ -47,7 +48,7 @@ export const runEpochMigration = async (ctx: Context, context: MigrationContext)
47
48
  timeout: LOAD_DOC_TIMEOUT,
48
49
  });
49
50
 
50
- const newRoot = context.echoHost.createDoc(rootHandle.docSync());
51
+ const newRoot = context.echoHost.createDoc(rootHandle.doc());
51
52
  await context.echoHost.flush();
52
53
  return { newRoot: newRoot.url };
53
54
  }
@@ -30,7 +30,7 @@ class TestAgent extends TestPeer {
30
30
  });
31
31
  }
32
32
 
33
- enableWriting() {
33
+ enableWriting(): void {
34
34
  this.notarizationPlugin.setWriter(this.feed);
35
35
  }
36
36