@dxos/echo-pipeline 0.6.2 → 0.6.3-main.0308ae2

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 (66) hide show
  1. package/dist/lib/browser/{chunk-UJQ5VS5V.mjs → chunk-6MJEONOX.mjs} +2569 -1066
  2. package/dist/lib/browser/chunk-6MJEONOX.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +12 -1049
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +224 -2
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/{chunk-RH6TDRML.cjs → chunk-PT5LWMPA.cjs} +3185 -1710
  9. package/dist/lib/node/chunk-PT5LWMPA.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +37 -1056
  11. package/dist/lib/node/index.cjs.map +4 -4
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +238 -13
  14. package/dist/lib/node/testing/index.cjs.map +4 -4
  15. package/dist/types/src/automerge/automerge-host.d.ts +29 -2
  16. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  17. package/dist/types/src/automerge/collection-synchronizer.d.ts +61 -0
  18. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -0
  19. package/dist/types/src/automerge/collection-synchronizer.test.d.ts +2 -0
  20. package/dist/types/src/automerge/collection-synchronizer.test.d.ts.map +1 -0
  21. package/dist/types/src/automerge/echo-network-adapter.d.ts +9 -2
  22. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  23. package/dist/types/src/automerge/echo-replicator.d.ts +7 -0
  24. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
  25. package/dist/types/src/automerge/heads-store.d.ts +1 -1
  26. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  27. package/dist/types/src/automerge/index.d.ts +2 -0
  28. package/dist/types/src/automerge/index.d.ts.map +1 -1
  29. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +3 -1
  30. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  31. package/dist/types/src/automerge/mesh-echo-replicator.d.ts +2 -2
  32. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  33. package/dist/types/src/automerge/network-protocol.d.ts +31 -0
  34. package/dist/types/src/automerge/network-protocol.d.ts.map +1 -0
  35. package/dist/types/src/automerge/space-collection.d.ts +4 -0
  36. package/dist/types/src/automerge/space-collection.d.ts.map +1 -0
  37. package/dist/types/src/db-host/data-service.d.ts +2 -1
  38. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  39. package/dist/types/src/db-host/documents-synchronizer.d.ts +1 -1
  40. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  41. package/dist/types/src/testing/index.d.ts +1 -0
  42. package/dist/types/src/testing/index.d.ts.map +1 -1
  43. package/dist/types/src/testing/test-replicator.d.ts +46 -0
  44. package/dist/types/src/testing/test-replicator.d.ts.map +1 -0
  45. package/package.json +33 -33
  46. package/src/automerge/automerge-host.test.ts +76 -14
  47. package/src/automerge/automerge-host.ts +219 -32
  48. package/src/automerge/automerge-repo.test.ts +2 -1
  49. package/src/automerge/collection-synchronizer.test.ts +91 -0
  50. package/src/automerge/collection-synchronizer.ts +204 -0
  51. package/src/automerge/echo-network-adapter.test.ts +5 -1
  52. package/src/automerge/echo-network-adapter.ts +69 -4
  53. package/src/automerge/echo-replicator.ts +9 -0
  54. package/src/automerge/heads-store.ts +6 -9
  55. package/src/automerge/index.ts +2 -0
  56. package/src/automerge/mesh-echo-replicator-connection.ts +6 -1
  57. package/src/automerge/mesh-echo-replicator.ts +28 -7
  58. package/src/automerge/network-protocol.ts +45 -0
  59. package/src/automerge/space-collection.ts +14 -0
  60. package/src/db-host/data-service.ts +26 -12
  61. package/src/db-host/documents-synchronizer.ts +17 -5
  62. package/src/metadata/metadata-store.ts +1 -1
  63. package/src/testing/index.ts +1 -0
  64. package/src/testing/test-replicator.ts +194 -0
  65. package/dist/lib/browser/chunk-UJQ5VS5V.mjs.map +0 -7
  66. package/dist/lib/node/chunk-RH6TDRML.cjs.map +0 -7
@@ -23,11 +23,16 @@ __export(testing_exports, {
23
23
  TestAgent: () => TestAgent,
24
24
  TestAgentBuilder: () => TestAgentBuilder,
25
25
  TestFeedBuilder: () => TestFeedBuilder,
26
+ TestReplicationNetwork: () => TestReplicationNetwork,
27
+ TestReplicator: () => TestReplicator,
28
+ TestReplicatorConnection: () => TestReplicatorConnection,
26
29
  WebsocketNetworkManagerProvider: () => WebsocketNetworkManagerProvider,
27
- changeStorageVersionInMetadata: () => changeStorageVersionInMetadata
30
+ brokenAutomergeReplicatorFactory: () => brokenAutomergeReplicatorFactory,
31
+ changeStorageVersionInMetadata: () => changeStorageVersionInMetadata,
32
+ testAutomergeReplicatorFactory: () => testAutomergeReplicatorFactory
28
33
  });
29
34
  module.exports = __toCommonJS(testing_exports);
30
- var import_chunk_RH6TDRML = require("../chunk-RH6TDRML.cjs");
35
+ var import_chunk_PT5LWMPA = require("../chunk-PT5LWMPA.cjs");
31
36
  var import_log = require("@dxos/log");
32
37
  var import_protocols = require("@dxos/protocols");
33
38
  var import_context = require("@dxos/context");
@@ -45,6 +50,11 @@ var import_async = require("@dxos/async");
45
50
  var import_automerge_repo = require("@dxos/automerge/automerge-repo");
46
51
  var import_invariant = require("@dxos/invariant");
47
52
  var import_log2 = require("@dxos/log");
53
+ var import_async2 = require("@dxos/async");
54
+ var import_context2 = require("@dxos/context");
55
+ var import_invariant2 = require("@dxos/invariant");
56
+ var import_log3 = require("@dxos/log");
57
+ var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
48
58
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/change-metadata.ts";
49
59
  var EchoMetadata = import_protocols.schema.getCodecForType("dxos.echo.metadata.EchoMetadata");
50
60
  var changeStorageVersionInMetadata = async (storage, version) => {
@@ -54,7 +64,7 @@ var changeStorageVersionInMetadata = async (storage, version) => {
54
64
  S: void 0,
55
65
  C: (f, a) => f(...a)
56
66
  });
57
- const metadata = new import_chunk_RH6TDRML.MetadataStore(storage.createDirectory("metadata"));
67
+ const metadata = new import_chunk_PT5LWMPA.MetadataStore(storage.createDirectory("metadata"));
58
68
  await metadata.load();
59
69
  const echoMetadata = metadata.metadata;
60
70
  echoMetadata.version = version;
@@ -65,7 +75,7 @@ var changeStorageVersionInMetadata = async (storage, version) => {
65
75
  var TestFeedBuilder = class extends import_testing.TestBuilder {
66
76
  constructor() {
67
77
  super({
68
- valueEncoding: import_chunk_RH6TDRML.valueEncoding
78
+ valueEncoding: import_chunk_PT5LWMPA.valueEncoding
69
79
  });
70
80
  }
71
81
  };
@@ -110,10 +120,10 @@ var TestAgentBuilder = class {
110
120
  };
111
121
  var TestAgent = class {
112
122
  get metadataStore() {
113
- return this._metadataStore ??= new import_chunk_RH6TDRML.MetadataStore(this.storage.createDirectory("metadata"));
123
+ return this._metadataStore ??= new import_chunk_PT5LWMPA.MetadataStore(this.storage.createDirectory("metadata"));
114
124
  }
115
125
  get snapshotStore() {
116
- return this._snapshotStore ??= new import_chunk_RH6TDRML.SnapshotStore(this.storage.createDirectory("snapshots"));
126
+ return this._snapshotStore ??= new import_chunk_PT5LWMPA.SnapshotStore(this.storage.createDirectory("snapshots"));
117
127
  }
118
128
  get blobStore() {
119
129
  return this._blobStore ??= new import_teleport_extension_object_sync.BlobStore(this.storage.createDirectory("blobs"));
@@ -140,7 +150,7 @@ var TestAgent = class {
140
150
  return this._spaces.get(spaceKey);
141
151
  }
142
152
  get spaceManager() {
143
- return this._spaceManager ??= new import_chunk_RH6TDRML.SpaceManager({
153
+ return this._spaceManager ??= new import_chunk_PT5LWMPA.SpaceManager({
144
154
  feedStore: this.feedStore,
145
155
  networkManager: this._networkManagerProvider(),
146
156
  metadataStore: this.metadataStore,
@@ -177,8 +187,8 @@ var TestAgent = class {
177
187
  metadata,
178
188
  swarmIdentity: {
179
189
  peerKey: this.deviceKey,
180
- credentialProvider: import_chunk_RH6TDRML.MOCK_AUTH_PROVIDER,
181
- credentialAuthenticator: import_chunk_RH6TDRML.MOCK_AUTH_VERIFIER
190
+ credentialProvider: import_chunk_PT5LWMPA.MOCK_AUTH_PROVIDER,
191
+ credentialAuthenticator: import_chunk_PT5LWMPA.MOCK_AUTH_VERIFIER
182
192
  },
183
193
  memberKey: identityKey,
184
194
  onAuthorizedConnection: (session) => {
@@ -201,12 +211,12 @@ var TestAgent = class {
201
211
  return space;
202
212
  }
203
213
  createSpaceProtocol(topic, gossip) {
204
- return new import_chunk_RH6TDRML.SpaceProtocol({
214
+ return new import_chunk_PT5LWMPA.SpaceProtocol({
205
215
  topic,
206
216
  swarmIdentity: {
207
217
  peerKey: this.deviceKey,
208
- credentialProvider: import_chunk_RH6TDRML.MOCK_AUTH_PROVIDER,
209
- credentialAuthenticator: import_chunk_RH6TDRML.MOCK_AUTH_VERIFIER
218
+ credentialProvider: import_chunk_PT5LWMPA.MOCK_AUTH_PROVIDER,
219
+ credentialAuthenticator: import_chunk_PT5LWMPA.MOCK_AUTH_VERIFIER
210
220
  },
211
221
  networkManager: this._networkManagerProvider(),
212
222
  blobStore: this.blobStore,
@@ -334,6 +344,216 @@ var TestAdapter = class _TestAdapter extends import_automerge_repo.NetworkAdapte
334
344
  this.emit("message", message);
335
345
  }
336
346
  };
347
+ function _ts_decorate(decorators, target, key, desc) {
348
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
349
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
350
+ r = Reflect.decorate(decorators, target, key, desc);
351
+ else
352
+ for (var i = decorators.length - 1; i >= 0; i--)
353
+ if (d = decorators[i])
354
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
355
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
356
+ }
357
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/test-replicator.ts";
358
+ var TestReplicationNetwork = class extends import_context2.Resource {
359
+ constructor(options = {}) {
360
+ super();
361
+ this._replicators = /* @__PURE__ */ new Set();
362
+ this._latency = void 0;
363
+ this._latency = options.latency;
364
+ }
365
+ async _close(ctx) {
366
+ for (const replicator of this._replicators) {
367
+ for (const connection of replicator.connections) {
368
+ void connection.writable.abort();
369
+ void connection.readable.cancel();
370
+ }
371
+ }
372
+ }
373
+ async createReplicator() {
374
+ const replicator = new TestReplicator({
375
+ onConnect: async () => {
376
+ (0, import_invariant2.invariant)(this._lifecycleState === import_context2.LifecycleState.OPEN, void 0, {
377
+ F: __dxlog_file4,
378
+ L: 45,
379
+ S: this,
380
+ A: [
381
+ "this._lifecycleState === LifecycleState.OPEN",
382
+ ""
383
+ ]
384
+ });
385
+ await this._connectReplicator(replicator);
386
+ },
387
+ onDisconnect: async () => {
388
+ (0, import_invariant2.invariant)(this._lifecycleState === import_context2.LifecycleState.OPEN, void 0, {
389
+ F: __dxlog_file4,
390
+ L: 49,
391
+ S: this,
392
+ A: [
393
+ "this._lifecycleState === LifecycleState.OPEN",
394
+ ""
395
+ ]
396
+ });
397
+ await this._disconnectReplicator(replicator);
398
+ }
399
+ });
400
+ this._replicators.add(replicator);
401
+ return replicator;
402
+ }
403
+ async _connectReplicator(replicator) {
404
+ for (const otherReplicator of this._replicators.values()) {
405
+ if (otherReplicator === replicator || !otherReplicator.connected) {
406
+ continue;
407
+ }
408
+ (0, import_log3.log)("create connection", {
409
+ from: replicator.context.peerId,
410
+ to: otherReplicator.context.peerId
411
+ }, {
412
+ F: __dxlog_file4,
413
+ L: 63,
414
+ S: this,
415
+ C: (f, a) => f(...a)
416
+ });
417
+ const [connection1, connection2] = this._createConnectionPair(replicator.context.peerId, otherReplicator.context.peerId);
418
+ await replicator.context.onConnectionOpen(connection1);
419
+ await otherReplicator.context.onConnectionOpen(connection2);
420
+ }
421
+ }
422
+ async _disconnectReplicator(replicator) {
423
+ for (const connection of replicator.connections) {
424
+ await replicator.context.onConnectionClosed(connection);
425
+ await connection.otherSide.owningReplicator.removeConnection(connection.otherSide);
426
+ }
427
+ }
428
+ _createConnectionPair(peer1, peer2) {
429
+ const LOG = false;
430
+ const forward = new TransformStream({
431
+ transform: async (message, controller) => {
432
+ if (LOG) {
433
+ import_log3.log.info("replicate", {
434
+ from: peer1,
435
+ to: peer2,
436
+ message
437
+ }, {
438
+ F: __dxlog_file4,
439
+ L: 86,
440
+ S: this,
441
+ C: (f, a) => f(...a)
442
+ });
443
+ }
444
+ if (this._latency !== void 0) {
445
+ await (0, import_async2.sleep)(this._latency);
446
+ }
447
+ controller.enqueue(message);
448
+ }
449
+ });
450
+ const backwards = new TransformStream({
451
+ transform: async (message, controller) => {
452
+ if (LOG) {
453
+ import_log3.log.info("replicate", {
454
+ from: peer2,
455
+ to: peer1,
456
+ message
457
+ }, {
458
+ F: __dxlog_file4,
459
+ L: 99,
460
+ S: this,
461
+ C: (f, a) => f(...a)
462
+ });
463
+ }
464
+ if (this._latency !== void 0) {
465
+ await (0, import_async2.sleep)(this._latency);
466
+ }
467
+ controller.enqueue(message);
468
+ }
469
+ });
470
+ const connection1 = new TestReplicatorConnection(peer2, backwards.readable, forward.writable);
471
+ const connection2 = new TestReplicatorConnection(peer1, forward.readable, backwards.writable);
472
+ connection1.otherSide = connection2;
473
+ connection2.otherSide = connection1;
474
+ return [
475
+ connection1,
476
+ connection2
477
+ ];
478
+ }
479
+ };
480
+ _ts_decorate([
481
+ import_async2.synchronized
482
+ ], TestReplicationNetwork.prototype, "_connectReplicator", null);
483
+ var TestReplicator = class {
484
+ constructor(_params) {
485
+ this._params = _params;
486
+ this.connected = false;
487
+ this.context = void 0;
488
+ this.connections = /* @__PURE__ */ new Set();
489
+ }
490
+ async connect(context) {
491
+ (0, import_log3.log)("connect", {
492
+ peerId: context.peerId
493
+ }, {
494
+ F: __dxlog_file4,
495
+ L: 131,
496
+ S: this,
497
+ C: (f, a) => f(...a)
498
+ });
499
+ this.context = context;
500
+ this.connected = true;
501
+ await this._params.onConnect();
502
+ }
503
+ async disconnect() {
504
+ (0, import_log3.log)("disconnect", {
505
+ peerId: this.context.peerId
506
+ }, {
507
+ F: __dxlog_file4,
508
+ L: 138,
509
+ S: this,
510
+ C: (f, a) => f(...a)
511
+ });
512
+ this.connected = false;
513
+ await this._params.onDisconnect();
514
+ }
515
+ async addConnection(connection) {
516
+ connection.owningReplicator = this;
517
+ this.connections.add(connection);
518
+ this.context.onConnectionOpen(connection);
519
+ }
520
+ async removeConnection(connection) {
521
+ connection.owningReplicator = void 0;
522
+ this.context.onConnectionClosed(connection);
523
+ this.connections.delete(connection);
524
+ }
525
+ };
526
+ var TestReplicatorConnection = class {
527
+ constructor(peerId, readable, writable) {
528
+ this.peerId = peerId;
529
+ this.readable = readable;
530
+ this.writable = writable;
531
+ this.otherSide = void 0;
532
+ this.owningReplicator = void 0;
533
+ }
534
+ async shouldAdvertise(params) {
535
+ return true;
536
+ }
537
+ shouldSyncCollection(params) {
538
+ return true;
539
+ }
540
+ };
541
+ var testAutomergeReplicatorFactory = (params) => {
542
+ return new import_teleport_extension_automerge_replicator.AutomergeReplicator({
543
+ ...params[0],
544
+ sendSyncRetryPolicy: {
545
+ retryBackoff: 20,
546
+ retriesBeforeBackoff: 2,
547
+ maxRetries: 3
548
+ }
549
+ }, params[1]);
550
+ };
551
+ var brokenAutomergeReplicatorFactory = (params) => {
552
+ params[1].onSyncMessage = () => {
553
+ throw new Error();
554
+ };
555
+ return testAutomergeReplicatorFactory(params);
556
+ };
337
557
  // Annotate the CommonJS export names for ESM import in node:
338
558
  0 && (module.exports = {
339
559
  MemoryNetworkManagerProvider,
@@ -341,7 +561,12 @@ var TestAdapter = class _TestAdapter extends import_automerge_repo.NetworkAdapte
341
561
  TestAgent,
342
562
  TestAgentBuilder,
343
563
  TestFeedBuilder,
564
+ TestReplicationNetwork,
565
+ TestReplicator,
566
+ TestReplicatorConnection,
344
567
  WebsocketNetworkManagerProvider,
345
- changeStorageVersionInMetadata
568
+ brokenAutomergeReplicatorFactory,
569
+ changeStorageVersionInMetadata,
570
+ testAutomergeReplicatorFactory
346
571
  });
347
572
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/testing/change-metadata.ts", "../../../../src/testing/test-agent-builder.ts", "../../../../src/testing/test-feed-builder.ts", "../../../../src/testing/test-network-adapter.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport type { Storage } from '@dxos/random-access-storage';\n\nimport { MetadataStore } from '../metadata';\n\nconst EchoMetadata = schema.getCodecForType('dxos.echo.metadata.EchoMetadata');\n\n/**\n * This function will change the storage version in the metadata.\n * This will break your storage and make it unusable.\n * Use this only for testing purposes.\n */\nexport const changeStorageVersionInMetadata = async (storage: Storage, version: number) => {\n log.info('Changing storage version in metadata. USE ONLY FOR TESTING.');\n const metadata = new MetadataStore(storage.createDirectory('metadata'));\n await metadata.load();\n const echoMetadata = metadata.metadata;\n echoMetadata.version = version;\n const file = metadata._directory.getOrCreateFile('EchoMetadata');\n await metadata._writeFile(file, EchoMetadata, echoMetadata);\n await metadata._directory.flush();\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\nimport { CredentialGenerator } from '@dxos/credentials';\nimport { type FeedStore } from '@dxos/feed-store';\nimport { type Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';\nimport { MemoryTransportFactory, SwarmNetworkManager, createSimplePeerTransportFactory } from '@dxos/network-manager';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\nimport { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';\nimport { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';\nimport { StorageType, createStorage, type Storage } from '@dxos/random-access-storage';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { BlobStore } from '@dxos/teleport-extension-object-sync';\nimport { ComplexMap } from '@dxos/util';\n\nimport { TestFeedBuilder } from './test-feed-builder';\nimport { SnapshotStore } from '../db-host';\nimport { MetadataStore } from '../metadata';\nimport { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, SpaceManager, SpaceProtocol, type Space } from '../space';\n\nexport type NetworkManagerProvider = () => SwarmNetworkManager;\n\nexport const MemoryNetworkManagerProvider =\n (signalContext: MemorySignalManagerContext): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new MemorySignalManager(signalContext),\n transportFactory: MemoryTransportFactory,\n });\n\nexport const WebsocketNetworkManagerProvider =\n (signalUrl: string): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new WebsocketSignalManager([{ server: signalUrl }]),\n transportFactory: createSimplePeerTransportFactory(),\n });\n\nexport type TestAgentBuilderOptions = {\n storage?: Storage;\n networkManagerProvider?: NetworkManagerProvider;\n};\n\n/**\n * Factory for test agents.\n */\nexport class TestAgentBuilder {\n private readonly _agents = new ComplexMap<PublicKey, TestAgent>(PublicKey.hash);\n private readonly _storage: Storage;\n private readonly _networkManagerProvider: NetworkManagerProvider;\n\n constructor({ storage, networkManagerProvider }: TestAgentBuilderOptions = {}) {\n this._storage = storage ?? createStorage({ type: StorageType.RAM });\n this._networkManagerProvider =\n networkManagerProvider ?? MemoryNetworkManagerProvider(new MemorySignalManagerContext());\n }\n\n async close() {\n return Promise.all(this.agents.map((agent) => agent.close()));\n }\n\n get agents() {\n return Array.from(this._agents.values());\n }\n\n getAgent(deviceKey: PublicKey) {\n return this._agents.get(deviceKey);\n }\n\n async createPeer(): Promise<TestAgent> {\n // prettier-ignore\n const feedBuilder = new TestFeedBuilder()\n .setStorage(this._storage, `agent-${this._agents.size}`);\n\n const identityKey = await feedBuilder.keyring.createKey();\n const deviceKey = await feedBuilder.keyring.createKey();\n\n const agent = new TestAgent(this._networkManagerProvider, feedBuilder, identityKey, deviceKey);\n this._agents.set(deviceKey, agent);\n return agent;\n }\n}\n\n/**\n * Test agent that enables the creation and replication of multiple spaces.\n */\nexport class TestAgent {\n private readonly _spaces = new ComplexMap<PublicKey, Space>(PublicKey.hash);\n\n public readonly storage: Storage;\n public readonly keyring: Keyring;\n public readonly feedStore: FeedStore<FeedMessage>;\n\n private _metadataStore?: MetadataStore;\n get metadataStore() {\n return (this._metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));\n }\n\n private _snapshotStore?: SnapshotStore;\n get snapshotStore() {\n return (this._snapshotStore ??= new SnapshotStore(this.storage.createDirectory('snapshots')));\n }\n\n private _blobStore?: BlobStore;\n get blobStore() {\n return (this._blobStore ??= new BlobStore(this.storage.createDirectory('blobs')));\n }\n\n constructor(\n private readonly _networkManagerProvider: NetworkManagerProvider,\n private readonly _feedBuilder: TestFeedBuilder,\n public readonly identityKey: PublicKey,\n public readonly deviceKey: PublicKey,\n ) {\n this.storage = this._feedBuilder.storage;\n this.keyring = this._feedBuilder.keyring;\n this.feedStore = this._feedBuilder.createFeedStore();\n }\n\n async close() {\n return Promise.all([...this.spaces.map((space) => space.close())]);\n }\n\n get spaces() {\n return Array.from(this._spaces.values());\n }\n\n getSpace(spaceKey: PublicKey) {\n return this._spaces.get(spaceKey);\n }\n\n private _spaceManager?: SpaceManager;\n get spaceManager() {\n return (this._spaceManager ??= new SpaceManager({\n feedStore: this.feedStore,\n networkManager: this._networkManagerProvider(),\n metadataStore: this.metadataStore,\n snapshotStore: this.snapshotStore,\n blobStore: this.blobStore,\n }));\n }\n\n async createSpace(\n identityKey: PublicKey = this.identityKey,\n spaceKey?: PublicKey,\n genesisKey?: PublicKey,\n dataKey?: PublicKey,\n saveMetadata = false,\n ): Promise<Space> {\n if (!spaceKey) {\n saveMetadata = true;\n spaceKey = await this.keyring.createKey();\n }\n if (!genesisKey) {\n genesisKey = await this.keyring.createKey();\n }\n\n const controlFeed = await this.feedStore.openFeed(genesisKey, { writable: true });\n const dataFeed = await this.feedStore.openFeed(dataKey ?? (await this.keyring.createKey()), {\n writable: true,\n sparse: true,\n });\n\n const metadata: SpaceMetadata = {\n key: spaceKey,\n genesisFeedKey: genesisKey,\n controlFeedKey: controlFeed.key,\n dataFeedKey: dataFeed.key,\n };\n if (saveMetadata) {\n await this.metadataStore.addSpace(metadata);\n }\n\n await this.spaceManager.open();\n const space = await this.spaceManager.constructSpace({\n metadata,\n swarmIdentity: {\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n memberKey: identityKey,\n onAuthorizedConnection: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n this.createGossip().createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n onDelegatedInvitationStatusChange: async () => {},\n onMemberRolesChanged: async () => {},\n });\n await space.setControlFeed(controlFeed);\n await space.setDataFeed(dataFeed);\n\n await space.open(new Context());\n\n this._spaces.set(spaceKey, space);\n return space;\n }\n\n createSpaceProtocol(topic: PublicKey, gossip?: Gossip) {\n return new SpaceProtocol({\n topic,\n swarmIdentity: {\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n networkManager: this._networkManagerProvider(),\n blobStore: this.blobStore,\n onSessionAuth: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n (gossip ?? this.createGossip()).createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n });\n }\n\n createGossip() {\n return new Gossip({\n localPeerId: this.deviceKey,\n });\n }\n\n createPresence(gossip?: Gossip) {\n return new Presence({\n announceInterval: 30,\n offlineTimeout: 200,\n identityKey: this.identityKey,\n gossip: gossip ?? this.createGossip(),\n });\n }\n\n async spaceGenesis(space: Space) {\n const generator = new CredentialGenerator(this.keyring, this.identityKey, this.deviceKey);\n const credentials = [\n ...(await generator.createSpaceGenesis(space.key, space.controlFeedKey!)),\n await generator.createFeedAdmission(space.key, space.dataFeedKey!, AdmittedFeed.Designation.DATA),\n await generator.createEpochCredential(space.key),\n ];\n\n for (const credential of credentials) {\n await space.controlPipeline.writer.write({\n credential: { credential },\n });\n }\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { TestBuilder } from '@dxos/feed-store/testing';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\n\nimport { valueEncoding } from '../common';\n\n/**\n * Builder with default encoder and generator.\n */\nexport class TestFeedBuilder extends TestBuilder<FeedMessage> {\n constructor() {\n super({\n valueEncoding,\n });\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger, sleep } from '@dxos/async';\nimport { type Message, NetworkAdapter, type PeerId } from '@dxos/automerge/automerge-repo';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nexport class TestAdapter extends NetworkAdapter {\n static createPair() {\n const adapter1: TestAdapter = new TestAdapter({\n send: (message: Message) => sleep(10).then(() => adapter2.receive(message)),\n });\n const adapter2: TestAdapter = new TestAdapter({\n send: (message: Message) => sleep(10).then(() => adapter1.receive(message)),\n });\n\n return [adapter1, adapter2];\n }\n\n public onConnect = new Trigger();\n\n constructor(private readonly _params: { send: (message: Message) => void }) {\n super();\n }\n\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n ready() {\n this.emit('ready', { network: this });\n }\n\n override connect(peerId: PeerId) {\n this.peerId = peerId;\n this.onConnect.wake();\n }\n\n peerCandidate(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-candidate', { peerId, peerMetadata: {} });\n }\n\n peerDisconnected(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-disconnected', { peerId });\n }\n\n override send(message: Message) {\n log('send', { from: message.senderId, to: message.targetId, type: message.type });\n this._params.send(message);\n }\n\n override disconnect() {\n this.peerId = undefined;\n }\n\n receive(message: Message) {\n invariant(this.peerId, 'Peer id is not set');\n this.emit('message', message);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_credentials", "import_log", "EchoMetadata", "schema", "getCodecForType", "changeStorageVersionInMetadata", "storage", "version", "log", "info", "metadata", "MetadataStore", "createDirectory", "load", "echoMetadata", "file", "_directory", "getOrCreateFile", "_writeFile", "flush", "TestFeedBuilder", "TestBuilder", "constructor", "valueEncoding", "MemoryNetworkManagerProvider", "signalContext", "SwarmNetworkManager", "signalManager", "MemorySignalManager", "transportFactory", "MemoryTransportFactory", "WebsocketNetworkManagerProvider", "signalUrl", "WebsocketSignalManager", "server", "createSimplePeerTransportFactory", "TestAgentBuilder", "networkManagerProvider", "_agents", "ComplexMap", "PublicKey", "hash", "_storage", "createStorage", "type", "StorageType", "RAM", "_networkManagerProvider", "MemorySignalManagerContext", "close", "Promise", "all", "agents", "map", "agent", "Array", "from", "values", "getAgent", "deviceKey", "get", "createPeer", "feedBuilder", "setStorage", "size", "identityKey", "keyring", "createKey", "TestAgent", "set", "metadataStore", "_metadataStore", "snapshotStore", "_snapshotStore", "SnapshotStore", "blobStore", "_blobStore", "BlobStore", "_feedBuilder", "_spaces", "feedStore", "createFeedStore", "spaces", "space", "getSpace", "spaceKey", "spaceManager", "_spaceManager", "SpaceManager", "networkManager", "createSpace", "genesisKey", "dataKey", "saveMetadata", "controlFeed", "openFeed", "writable", "dataFeed", "sparse", "key", "genesisFeedKey", "controlFeedKey", "dataFeedKey", "addSpace", "open", "constructSpace", "swarmIdentity", "peerKey", "credentialProvider", "MOCK_AUTH_PROVIDER", "credentialAuthenticator", "MOCK_AUTH_VERIFIER", "memberKey", "onAuthorizedConnection", "session", "addExtension", "createGossip", "createExtension", "remotePeerId", "onDelegatedInvitationStatusChange", "onMemberRolesChanged", "setControlFeed", "setDataFeed", "Context", "createSpaceProtocol", "topic", "gossip", "SpaceProtocol", "onSessionAuth", "Gossip", "localPeerId", "createPresence", "Presence", "announceInterval", "offlineTimeout", "spaceGenesis", "generator", "CredentialGenerator", "credentials", "createSpaceGenesis", "createFeedAdmission", "AdmittedFeed", "Designation", "DATA", "createEpochCredential", "credential", "controlPipeline", "writer", "write", "TestAdapter", "NetworkAdapter", "_params", "onConnect", "Trigger", "createPair", "adapter1", "send", "message", "sleep", "then", "adapter2", "receive", "ready", "emit", "network", "connect", "peerId", "wake", "peerCandidate", "invariant", "peerMetadata", "peerDisconnected", "senderId", "to", "targetId", "disconnect", "undefined"]
3
+ "sources": ["../../../../src/testing/change-metadata.ts", "../../../../src/testing/test-agent-builder.ts", "../../../../src/testing/test-feed-builder.ts", "../../../../src/testing/test-network-adapter.ts", "../../../../src/testing/test-replicator.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport type { Storage } from '@dxos/random-access-storage';\n\nimport { MetadataStore } from '../metadata';\n\nconst EchoMetadata = schema.getCodecForType('dxos.echo.metadata.EchoMetadata');\n\n/**\n * This function will change the storage version in the metadata.\n * This will break your storage and make it unusable.\n * Use this only for testing purposes.\n */\nexport const changeStorageVersionInMetadata = async (storage: Storage, version: number) => {\n log.info('Changing storage version in metadata. USE ONLY FOR TESTING.');\n const metadata = new MetadataStore(storage.createDirectory('metadata'));\n await metadata.load();\n const echoMetadata = metadata.metadata;\n echoMetadata.version = version;\n const file = metadata._directory.getOrCreateFile('EchoMetadata');\n await metadata._writeFile(file, EchoMetadata, echoMetadata);\n await metadata._directory.flush();\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\nimport { CredentialGenerator } from '@dxos/credentials';\nimport { type FeedStore } from '@dxos/feed-store';\nimport { type Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';\nimport { MemoryTransportFactory, SwarmNetworkManager, createSimplePeerTransportFactory } from '@dxos/network-manager';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\nimport { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';\nimport { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';\nimport { StorageType, createStorage, type Storage } from '@dxos/random-access-storage';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { BlobStore } from '@dxos/teleport-extension-object-sync';\nimport { ComplexMap } from '@dxos/util';\n\nimport { TestFeedBuilder } from './test-feed-builder';\nimport { SnapshotStore } from '../db-host';\nimport { MetadataStore } from '../metadata';\nimport { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, SpaceManager, SpaceProtocol, type Space } from '../space';\n\nexport type NetworkManagerProvider = () => SwarmNetworkManager;\n\nexport const MemoryNetworkManagerProvider =\n (signalContext: MemorySignalManagerContext): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new MemorySignalManager(signalContext),\n transportFactory: MemoryTransportFactory,\n });\n\nexport const WebsocketNetworkManagerProvider =\n (signalUrl: string): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new WebsocketSignalManager([{ server: signalUrl }]),\n transportFactory: createSimplePeerTransportFactory(),\n });\n\nexport type TestAgentBuilderOptions = {\n storage?: Storage;\n networkManagerProvider?: NetworkManagerProvider;\n};\n\n/**\n * Factory for test agents.\n */\nexport class TestAgentBuilder {\n private readonly _agents = new ComplexMap<PublicKey, TestAgent>(PublicKey.hash);\n private readonly _storage: Storage;\n private readonly _networkManagerProvider: NetworkManagerProvider;\n\n constructor({ storage, networkManagerProvider }: TestAgentBuilderOptions = {}) {\n this._storage = storage ?? createStorage({ type: StorageType.RAM });\n this._networkManagerProvider =\n networkManagerProvider ?? MemoryNetworkManagerProvider(new MemorySignalManagerContext());\n }\n\n async close() {\n return Promise.all(this.agents.map((agent) => agent.close()));\n }\n\n get agents() {\n return Array.from(this._agents.values());\n }\n\n getAgent(deviceKey: PublicKey) {\n return this._agents.get(deviceKey);\n }\n\n async createPeer(): Promise<TestAgent> {\n // prettier-ignore\n const feedBuilder = new TestFeedBuilder()\n .setStorage(this._storage, `agent-${this._agents.size}`);\n\n const identityKey = await feedBuilder.keyring.createKey();\n const deviceKey = await feedBuilder.keyring.createKey();\n\n const agent = new TestAgent(this._networkManagerProvider, feedBuilder, identityKey, deviceKey);\n this._agents.set(deviceKey, agent);\n return agent;\n }\n}\n\n/**\n * Test agent that enables the creation and replication of multiple spaces.\n */\nexport class TestAgent {\n private readonly _spaces = new ComplexMap<PublicKey, Space>(PublicKey.hash);\n\n public readonly storage: Storage;\n public readonly keyring: Keyring;\n public readonly feedStore: FeedStore<FeedMessage>;\n\n private _metadataStore?: MetadataStore;\n get metadataStore() {\n return (this._metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));\n }\n\n private _snapshotStore?: SnapshotStore;\n get snapshotStore() {\n return (this._snapshotStore ??= new SnapshotStore(this.storage.createDirectory('snapshots')));\n }\n\n private _blobStore?: BlobStore;\n get blobStore() {\n return (this._blobStore ??= new BlobStore(this.storage.createDirectory('blobs')));\n }\n\n constructor(\n private readonly _networkManagerProvider: NetworkManagerProvider,\n private readonly _feedBuilder: TestFeedBuilder,\n public readonly identityKey: PublicKey,\n public readonly deviceKey: PublicKey,\n ) {\n this.storage = this._feedBuilder.storage;\n this.keyring = this._feedBuilder.keyring;\n this.feedStore = this._feedBuilder.createFeedStore();\n }\n\n async close() {\n return Promise.all([...this.spaces.map((space) => space.close())]);\n }\n\n get spaces() {\n return Array.from(this._spaces.values());\n }\n\n getSpace(spaceKey: PublicKey) {\n return this._spaces.get(spaceKey);\n }\n\n private _spaceManager?: SpaceManager;\n get spaceManager() {\n return (this._spaceManager ??= new SpaceManager({\n feedStore: this.feedStore,\n networkManager: this._networkManagerProvider(),\n metadataStore: this.metadataStore,\n snapshotStore: this.snapshotStore,\n blobStore: this.blobStore,\n }));\n }\n\n async createSpace(\n identityKey: PublicKey = this.identityKey,\n spaceKey?: PublicKey,\n genesisKey?: PublicKey,\n dataKey?: PublicKey,\n saveMetadata = false,\n ): Promise<Space> {\n if (!spaceKey) {\n saveMetadata = true;\n spaceKey = await this.keyring.createKey();\n }\n if (!genesisKey) {\n genesisKey = await this.keyring.createKey();\n }\n\n const controlFeed = await this.feedStore.openFeed(genesisKey, { writable: true });\n const dataFeed = await this.feedStore.openFeed(dataKey ?? (await this.keyring.createKey()), {\n writable: true,\n sparse: true,\n });\n\n const metadata: SpaceMetadata = {\n key: spaceKey,\n genesisFeedKey: genesisKey,\n controlFeedKey: controlFeed.key,\n dataFeedKey: dataFeed.key,\n };\n if (saveMetadata) {\n await this.metadataStore.addSpace(metadata);\n }\n\n await this.spaceManager.open();\n const space = await this.spaceManager.constructSpace({\n metadata,\n swarmIdentity: {\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n memberKey: identityKey,\n onAuthorizedConnection: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n this.createGossip().createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n onDelegatedInvitationStatusChange: async () => {},\n onMemberRolesChanged: async () => {},\n });\n await space.setControlFeed(controlFeed);\n await space.setDataFeed(dataFeed);\n\n await space.open(new Context());\n\n this._spaces.set(spaceKey, space);\n return space;\n }\n\n createSpaceProtocol(topic: PublicKey, gossip?: Gossip) {\n return new SpaceProtocol({\n topic,\n swarmIdentity: {\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n networkManager: this._networkManagerProvider(),\n blobStore: this.blobStore,\n onSessionAuth: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n (gossip ?? this.createGossip()).createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n });\n }\n\n createGossip() {\n return new Gossip({\n localPeerId: this.deviceKey,\n });\n }\n\n createPresence(gossip?: Gossip) {\n return new Presence({\n announceInterval: 30,\n offlineTimeout: 200,\n identityKey: this.identityKey,\n gossip: gossip ?? this.createGossip(),\n });\n }\n\n async spaceGenesis(space: Space) {\n const generator = new CredentialGenerator(this.keyring, this.identityKey, this.deviceKey);\n const credentials = [\n ...(await generator.createSpaceGenesis(space.key, space.controlFeedKey!)),\n await generator.createFeedAdmission(space.key, space.dataFeedKey!, AdmittedFeed.Designation.DATA),\n await generator.createEpochCredential(space.key),\n ];\n\n for (const credential of credentials) {\n await space.controlPipeline.writer.write({\n credential: { credential },\n });\n }\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { TestBuilder } from '@dxos/feed-store/testing';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\n\nimport { valueEncoding } from '../common';\n\n/**\n * Builder with default encoder and generator.\n */\nexport class TestFeedBuilder extends TestBuilder<FeedMessage> {\n constructor() {\n super({\n valueEncoding,\n });\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger, sleep } from '@dxos/async';\nimport { type Message, NetworkAdapter, type PeerId } from '@dxos/automerge/automerge-repo';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nexport class TestAdapter extends NetworkAdapter {\n static createPair() {\n const adapter1: TestAdapter = new TestAdapter({\n send: (message: Message) => sleep(10).then(() => adapter2.receive(message)),\n });\n const adapter2: TestAdapter = new TestAdapter({\n send: (message: Message) => sleep(10).then(() => adapter1.receive(message)),\n });\n\n return [adapter1, adapter2];\n }\n\n public onConnect = new Trigger();\n\n constructor(private readonly _params: { send: (message: Message) => void }) {\n super();\n }\n\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n ready() {\n this.emit('ready', { network: this });\n }\n\n override connect(peerId: PeerId) {\n this.peerId = peerId;\n this.onConnect.wake();\n }\n\n peerCandidate(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-candidate', { peerId, peerMetadata: {} });\n }\n\n peerDisconnected(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-disconnected', { peerId });\n }\n\n override send(message: Message) {\n log('send', { from: message.senderId, to: message.targetId, type: message.type });\n this._params.send(message);\n }\n\n override disconnect() {\n this.peerId = undefined;\n }\n\n receive(message: Message) {\n invariant(this.peerId, 'Peer id is not set');\n this.emit('message', message);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep, synchronized } from '@dxos/async';\nimport { type Message } from '@dxos/automerge/automerge-repo';\nimport { type Context, LifecycleState, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { AutomergeReplicator, type AutomergeReplicatorFactory } from '@dxos/teleport-extension-automerge-replicator';\n\nimport type {\n EchoReplicator,\n EchoReplicatorContext,\n ReplicatorConnection,\n ShouldAdvertiseParams,\n ShouldSyncCollectionParams,\n} from '../automerge';\n\nexport type TestReplicatorNetworkOptions = {\n latency?: number;\n};\n\nexport class TestReplicationNetwork extends Resource {\n private readonly _replicators = new Set<TestReplicator>();\n private readonly _latency?: number = undefined;\n\n constructor(options: TestReplicatorNetworkOptions = {}) {\n super();\n this._latency = options.latency;\n }\n\n protected override async _close(ctx: Context): Promise<void> {\n for (const replicator of this._replicators) {\n for (const connection of replicator.connections) {\n void connection.writable.abort();\n void connection.readable.cancel();\n }\n }\n }\n\n async createReplicator(): Promise<TestReplicator> {\n const replicator = new TestReplicator({\n onConnect: async () => {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n await this._connectReplicator(replicator);\n },\n onDisconnect: async () => {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n await this._disconnectReplicator(replicator);\n },\n });\n this._replicators.add(replicator);\n return replicator;\n }\n\n @synchronized\n private async _connectReplicator(replicator: TestReplicator) {\n for (const otherReplicator of this._replicators.values()) {\n if (otherReplicator === replicator || !otherReplicator.connected) {\n continue;\n }\n log('create connection', { from: replicator.context!.peerId, to: otherReplicator.context!.peerId });\n const [connection1, connection2] = this._createConnectionPair(\n replicator.context!.peerId,\n otherReplicator.context!.peerId,\n );\n await replicator.context!.onConnectionOpen(connection1);\n await otherReplicator.context!.onConnectionOpen(connection2);\n }\n }\n\n private async _disconnectReplicator(replicator: TestReplicator) {\n for (const connection of replicator.connections) {\n await replicator.context!.onConnectionClosed(connection);\n await connection.otherSide!.owningReplicator!.removeConnection(connection.otherSide!);\n }\n }\n\n private _createConnectionPair(peer1: string, peer2: string): [TestReplicatorConnection, TestReplicatorConnection] {\n const LOG = false;\n\n const forward = new TransformStream({\n transform: async (message, controller) => {\n if (LOG) {\n log.info('replicate', { from: peer1, to: peer2, message });\n }\n\n if (this._latency !== undefined) {\n await sleep(this._latency);\n }\n\n controller.enqueue(message);\n },\n });\n const backwards = new TransformStream({\n transform: async (message, controller) => {\n if (LOG) {\n log.info('replicate', { from: peer2, to: peer1, message });\n }\n\n if (this._latency !== undefined) {\n await sleep(this._latency);\n }\n\n controller.enqueue(message);\n },\n });\n\n const connection1 = new TestReplicatorConnection(peer2, backwards.readable, forward.writable);\n const connection2 = new TestReplicatorConnection(peer1, forward.readable, backwards.writable);\n connection1.otherSide = connection2;\n connection2.otherSide = connection1;\n return [connection1, connection2];\n }\n}\n\ntype TestReplicatorParams = {\n onConnect: () => Promise<void>;\n onDisconnect: () => Promise<void>;\n};\n\nexport class TestReplicator implements EchoReplicator {\n constructor(private readonly _params: TestReplicatorParams) {}\n\n public connected = false;\n public context: EchoReplicatorContext | undefined = undefined;\n public connections = new Set<TestReplicatorConnection>();\n\n async connect(context: EchoReplicatorContext): Promise<void> {\n log('connect', { peerId: context.peerId });\n this.context = context;\n this.connected = true;\n await this._params.onConnect();\n }\n\n async disconnect(): Promise<void> {\n log('disconnect', { peerId: this.context!.peerId });\n this.connected = false;\n await this._params.onDisconnect();\n }\n\n async addConnection(connection: TestReplicatorConnection): Promise<void> {\n connection.owningReplicator = this;\n this.connections.add(connection);\n this.context!.onConnectionOpen(connection);\n }\n\n async removeConnection(connection: TestReplicatorConnection): Promise<void> {\n connection.owningReplicator = undefined;\n this.context!.onConnectionClosed(connection);\n this.connections.delete(connection);\n }\n}\n\nexport class TestReplicatorConnection implements ReplicatorConnection {\n public otherSide: TestReplicatorConnection | undefined = undefined;\n public owningReplicator: TestReplicator | undefined = undefined;\n\n constructor(\n public readonly peerId: string,\n public readonly readable: ReadableStream<Message>,\n public readonly writable: WritableStream<Message>,\n ) {}\n\n async shouldAdvertise(params: ShouldAdvertiseParams): Promise<boolean> {\n return true;\n }\n\n shouldSyncCollection(params: ShouldSyncCollectionParams): boolean {\n return true;\n }\n}\n\nexport const testAutomergeReplicatorFactory: AutomergeReplicatorFactory = (params) => {\n return new AutomergeReplicator(\n {\n ...params[0],\n sendSyncRetryPolicy: {\n retryBackoff: 20,\n retriesBeforeBackoff: 2,\n maxRetries: 3,\n },\n },\n params[1],\n );\n};\n\nexport const brokenAutomergeReplicatorFactory: AutomergeReplicatorFactory = (params) => {\n params[1]!.onSyncMessage = () => {\n throw new Error();\n };\n return testAutomergeReplicatorFactory(params);\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_credentials", "import_log", "import_async", "import_context", "import_invariant", "EchoMetadata", "schema", "getCodecForType", "changeStorageVersionInMetadata", "storage", "version", "log", "info", "metadata", "MetadataStore", "createDirectory", "load", "echoMetadata", "file", "_directory", "getOrCreateFile", "_writeFile", "flush", "TestFeedBuilder", "TestBuilder", "constructor", "valueEncoding", "MemoryNetworkManagerProvider", "signalContext", "SwarmNetworkManager", "signalManager", "MemorySignalManager", "transportFactory", "MemoryTransportFactory", "WebsocketNetworkManagerProvider", "signalUrl", "WebsocketSignalManager", "server", "createSimplePeerTransportFactory", "TestAgentBuilder", "networkManagerProvider", "_agents", "ComplexMap", "PublicKey", "hash", "_storage", "createStorage", "type", "StorageType", "RAM", "_networkManagerProvider", "MemorySignalManagerContext", "close", "Promise", "all", "agents", "map", "agent", "Array", "from", "values", "getAgent", "deviceKey", "get", "createPeer", "feedBuilder", "setStorage", "size", "identityKey", "keyring", "createKey", "TestAgent", "set", "metadataStore", "_metadataStore", "snapshotStore", "_snapshotStore", "SnapshotStore", "blobStore", "_blobStore", "BlobStore", "_feedBuilder", "_spaces", "feedStore", "createFeedStore", "spaces", "space", "getSpace", "spaceKey", "spaceManager", "_spaceManager", "SpaceManager", "networkManager", "createSpace", "genesisKey", "dataKey", "saveMetadata", "controlFeed", "openFeed", "writable", "dataFeed", "sparse", "key", "genesisFeedKey", "controlFeedKey", "dataFeedKey", "addSpace", "open", "constructSpace", "swarmIdentity", "peerKey", "credentialProvider", "MOCK_AUTH_PROVIDER", "credentialAuthenticator", "MOCK_AUTH_VERIFIER", "memberKey", "onAuthorizedConnection", "session", "addExtension", "createGossip", "createExtension", "remotePeerId", "onDelegatedInvitationStatusChange", "onMemberRolesChanged", "setControlFeed", "setDataFeed", "Context", "createSpaceProtocol", "topic", "gossip", "SpaceProtocol", "onSessionAuth", "Gossip", "localPeerId", "createPresence", "Presence", "announceInterval", "offlineTimeout", "spaceGenesis", "generator", "CredentialGenerator", "credentials", "createSpaceGenesis", "createFeedAdmission", "AdmittedFeed", "Designation", "DATA", "createEpochCredential", "credential", "controlPipeline", "writer", "write", "TestAdapter", "NetworkAdapter", "_params", "onConnect", "Trigger", "createPair", "adapter1", "send", "message", "sleep", "then", "adapter2", "receive", "ready", "emit", "network", "connect", "peerId", "wake", "peerCandidate", "invariant", "peerMetadata", "peerDisconnected", "senderId", "to", "targetId", "disconnect", "undefined", "TestReplicationNetwork", "Resource", "options", "_replicators", "Set", "_latency", "latency", "_close", "ctx", "replicator", "connection", "connections", "abort", "readable", "cancel", "createReplicator", "TestReplicator", "_lifecycleState", "LifecycleState", "OPEN", "_connectReplicator", "onDisconnect", "_disconnectReplicator", "add", "otherReplicator", "connected", "context", "connection1", "connection2", "_createConnectionPair", "onConnectionOpen", "onConnectionClosed", "otherSide", "owningReplicator", "removeConnection", "peer1", "peer2", "LOG", "forward", "TransformStream", "transform", "controller", "enqueue", "backwards", "TestReplicatorConnection", "synchronized", "addConnection", "delete", "shouldAdvertise", "params", "shouldSyncCollection", "testAutomergeReplicatorFactory", "AutomergeReplicator", "sendSyncRetryPolicy", "retryBackoff", "retriesBeforeBackoff", "maxRetries", "brokenAutomergeReplicatorFactory", "onSyncMessage", "Error"]
7
7
  }
@@ -1,10 +1,11 @@
1
1
  import { type Doc, type Heads } from '@dxos/automerge/automerge';
2
- import { Repo, type AnyDocumentId, type DocHandle, type DocumentId } from '@dxos/automerge/automerge-repo';
2
+ import { Repo, type AnyDocumentId, type DocHandle, type DocumentId, type PeerId } from '@dxos/automerge/automerge-repo';
3
3
  import { Context, Resource } from '@dxos/context';
4
4
  import { type SpaceDoc } from '@dxos/echo-protocol';
5
5
  import { type IndexMetadataStore } from '@dxos/indexing';
6
6
  import { type LevelDB } from '@dxos/kv-store';
7
7
  import { type DocHeadsList, type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';
8
+ import { type CollectionState } from './collection-synchronizer';
8
9
  import { type EchoReplicator } from './echo-replicator';
9
10
  export type AutomergeHostParams = {
10
11
  db: LevelDB;
@@ -26,6 +27,7 @@ export declare class AutomergeHost extends Resource {
26
27
  private readonly _db;
27
28
  private readonly _indexMetadataStore;
28
29
  private readonly _echoNetworkAdapter;
30
+ private readonly _collectionSynchronizer;
29
31
  private _repo;
30
32
  private _storage;
31
33
  private readonly _headsStore;
@@ -37,6 +39,7 @@ export declare class AutomergeHost extends Resource {
37
39
  * @deprecated To be abstracted away.
38
40
  */
39
41
  get repo(): Repo;
42
+ get peerId(): PeerId;
40
43
  get loadedDocsCount(): number;
41
44
  addReplicator(replicator: EchoReplicator): Promise<void>;
42
45
  removeReplicator(replicator: EchoReplicator): Promise<void>;
@@ -52,6 +55,7 @@ export declare class AutomergeHost extends Resource {
52
55
  reIndexHeads(documentIds: DocumentId[]): Promise<void>;
53
56
  private _sharePolicy;
54
57
  private _beforeSave;
58
+ private _shouldSyncCollection;
55
59
  /**
56
60
  * Called by AutomergeStorageAdapter after levelDB batch commit.
57
61
  */
@@ -63,7 +67,30 @@ export declare class AutomergeHost extends Resource {
63
67
  * Flush documents to disk.
64
68
  */
65
69
  flush({ documentIds }?: FlushRequest): Promise<void>;
66
- getHeads(documentId: DocumentId): Promise<Heads | undefined>;
70
+ getHeads(documentIds: DocumentId[]): Promise<(Heads | undefined)[]>;
71
+ getLocalCollectionState(collectionId: string): CollectionState | undefined;
72
+ getRemoteCollectionStates(collectionId: string): ReadonlyMap<PeerId, CollectionState>;
73
+ refreshCollection(collectionId: string): void;
74
+ getCollectionSyncState(collectionId: string): Promise<CollectionSyncState>;
75
+ /**
76
+ * Update the local collection state based on the locally stored document heads.
77
+ */
78
+ updateLocalCollectionState(collectionId: string, documentIds: DocumentId[]): Promise<void>;
79
+ private _onCollectionStateQueried;
80
+ private _onCollectionStateReceived;
81
+ private _queryCollectionState;
82
+ private _sendCollectionState;
83
+ private _onPeerConnected;
84
+ private _onPeerDisconnected;
85
+ private _onRemoteCollectionStateUpdated;
86
+ private _onHeadsChanged;
67
87
  }
68
88
  export declare const getSpaceKeyFromDoc: (doc: Doc<SpaceDoc>) => string | null;
89
+ export type CollectionSyncState = {
90
+ peers: PeerSyncState[];
91
+ };
92
+ export type PeerSyncState = {
93
+ peerId: PeerId;
94
+ differentDocuments: number;
95
+ };
69
96
  //# sourceMappingURL=automerge-host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"automerge-host.d.ts","sourceRoot":"","sources":["../../../../src/automerge/automerge-host.ts"],"names":[],"mappings":"AAKA,OAAO,EAOL,KAAK,GAAG,EACR,KAAK,KAAK,EACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,IAAI,EACJ,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,UAAU,EAGhB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAqC,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAK/F,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIxD,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,OAAO,CAAC;IAEZ,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,qBACa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAEjC;IAEH,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IAGzC,OAAO,CAAC,OAAO,CAAU;gBAEb,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,mBAAmB;cAclC,KAAK;cAqBL,MAAM;IAM/B;;OAEG;IACH,IAAI,IAAI,IAAI,IAAI,CAEf;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAEK,aAAa,CAAC,UAAU,EAAE,cAAc;IAIxC,gBAAgB,CAAC,UAAU,EAAE,cAAc;IAIjD;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAsBvG;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,CAAC,CAAC;IAYxE,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5D,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE;YAyB9B,YAAY;YAiBZ,WAAW;IAwBzB;;OAEG;YACW,UAAU;IAKxB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,eAAe;YAIT,8BAA8B;IAc5C;;OAEG;IAEG,KAAK,CAAC,EAAE,WAAW,EAAE,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAYnE;AAED,eAAO,MAAM,kBAAkB,QAAS,IAAI,QAAQ,CAAC,KAAG,MAAM,GAAG,IAQhE,CAAC"}
1
+ {"version":3,"file":"automerge-host.d.ts","sourceRoot":"","sources":["../../../../src/automerge/automerge-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { Event } from '@dxos/async';
2
+ import type { DocumentId, PeerId } from '@dxos/automerge/automerge-repo';
3
+ import { Resource, type Context } from '@dxos/context';
4
+ export type CollectionSynchronizerParams = {
5
+ sendCollectionState: (collectionId: string, peerId: PeerId, state: CollectionState) => void;
6
+ queryCollectionState: (collectionId: string, peerId: PeerId) => void;
7
+ shouldSyncCollection: (collectionId: string, peerId: PeerId) => boolean;
8
+ };
9
+ /**
10
+ * Implements collection sync protocol.
11
+ */
12
+ export declare class CollectionSynchronizer extends Resource {
13
+ private readonly _sendCollectionState;
14
+ private readonly _queryCollectionState;
15
+ private readonly _shouldSyncCollection;
16
+ /**
17
+ * CollectionId -> State.
18
+ */
19
+ private readonly _perCollectionStates;
20
+ private readonly _connectedPeers;
21
+ readonly remoteStateUpdated: Event<{
22
+ collectionId: string;
23
+ peerId: PeerId;
24
+ }>;
25
+ constructor(params: CollectionSynchronizerParams);
26
+ protected _open(ctx: Context): Promise<void>;
27
+ getRegisteredCollectionIds(): string[];
28
+ getLocalCollectionState(collectionId: string): CollectionState | undefined;
29
+ setLocalCollectionState(collectionId: string, state: CollectionState): void;
30
+ getRemoteCollectionStates(collectionId: string): ReadonlyMap<PeerId, CollectionState>;
31
+ refreshCollection(collectionId: string): void;
32
+ /**
33
+ * Callback when a connection to a peer is established.
34
+ */
35
+ onConnectionOpen(peerId: PeerId): void;
36
+ /**
37
+ * Callback when a connection to a peer is closed.
38
+ */
39
+ onConnectionClosed(peerId: PeerId): void;
40
+ /**
41
+ * Callback when a peer queries the state of a collection.
42
+ */
43
+ onCollectionStateQueried(collectionId: string, peerId: PeerId): void;
44
+ /**
45
+ * Callback when a peer sends the state of a collection.
46
+ */
47
+ onRemoteStateReceived(collectionId: string, peerId: PeerId, state: CollectionState): void;
48
+ private _getPerCollectionState;
49
+ private _refreshInterestedPeers;
50
+ }
51
+ export type CollectionState = {
52
+ /**
53
+ * DocumentId -> Heads.
54
+ */
55
+ documents: Record<string, string[]>;
56
+ };
57
+ export type CollectionStateDiff = {
58
+ different: DocumentId[];
59
+ };
60
+ export declare const diffCollectionState: (local: CollectionState, remote: CollectionState) => CollectionStateDiff;
61
+ //# sourceMappingURL=collection-synchronizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-synchronizer.d.ts","sourceRoot":"","sources":["../../../../src/automerge/collection-synchronizer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,EAAsC,MAAM,aAAa,CAAC;AAErF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAOvD,MAAM,MAAM,4BAA4B,GAAG;IACzC,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5F,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACzE,CAAC;AAEF;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;IAClD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsD;IAC3F,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuD;IAC7F,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuD;IAE7F;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAyC;IAE9E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErD,SAAgB,kBAAkB;sBAA6B,MAAM;gBAAU,MAAM;OAAM;gBAE/E,MAAM,EAAE,4BAA4B;cAOvB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3D,0BAA0B,IAAI,MAAM,EAAE;IAItC,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1E,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe;IAWpE,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC;IAIrF,iBAAiB,CAAC,YAAY,EAAE,MAAM;IAmBtC;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM;IAiB/B;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM;IAQjC;;OAEG;IACH,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAQ7D;;OAEG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe;IAMlF,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,uBAAuB;CAShC;AASD,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,UAAW,eAAe,UAAU,eAAe,KAAG,mBAerF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=collection-synchronizer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-synchronizer.test.d.ts","sourceRoot":"","sources":["../../../../src/automerge/collection-synchronizer.test.ts"],"names":[],"mappings":""}
@@ -1,8 +1,10 @@
1
- import { type Message, NetworkAdapter, type PeerId, type PeerMetadata } from '@dxos/automerge/automerge-repo';
1
+ import { NetworkAdapter, type Message, type PeerId, type PeerMetadata } from '@dxos/automerge/automerge-repo';
2
2
  import { type PublicKey } from '@dxos/keys';
3
- import { type EchoReplicator, type ShouldAdvertiseParams } from './echo-replicator';
3
+ import { type EchoReplicator, type ShouldAdvertiseParams, type ShouldSyncCollectionParams } from './echo-replicator';
4
4
  export type EchoNetworkAdapterParams = {
5
5
  getContainingSpaceForDocument: (documentId: string) => Promise<PublicKey | null>;
6
+ onCollectionStateQueried: (collectionId: string, peerId: PeerId) => void;
7
+ onCollectionStateReceived: (collectionId: string, peerId: PeerId, state: unknown) => void;
6
8
  };
7
9
  /**
8
10
  * Manages a set of {@link EchoReplicator} instances.
@@ -26,7 +28,12 @@ export declare class EchoNetworkAdapter extends NetworkAdapter {
26
28
  addReplicator(replicator: EchoReplicator): Promise<void>;
27
29
  removeReplicator(replicator: EchoReplicator): Promise<void>;
28
30
  shouldAdvertise(peerId: PeerId, params: ShouldAdvertiseParams): Promise<boolean>;
31
+ shouldSyncCollection(peerId: PeerId, params: ShouldSyncCollectionParams): boolean;
32
+ queryCollectionState(collectionId: string, targetId: PeerId): void;
33
+ sendCollectionState(collectionId: string, targetId: PeerId, state: unknown): void;
34
+ getPeersInterestedInCollection(collectionId: string): PeerId[];
29
35
  private _onConnectionOpen;
36
+ private _onMessage;
30
37
  /**
31
38
  * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.
32
39
  * TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo