@dxos/echo-pipeline 0.7.4 → 0.7.5-main.9cb18ac

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 (39) hide show
  1. package/dist/lib/browser/{chunk-LZK5YFYE.mjs → chunk-KY5AZOEF.mjs} +26 -8
  2. package/dist/lib/browser/{chunk-LZK5YFYE.mjs.map → chunk-KY5AZOEF.mjs.map} +3 -3
  3. package/dist/lib/browser/index.mjs +113 -64
  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/node/{chunk-MACQJ2EP.cjs → chunk-SXCQEIFA.cjs} +29 -11
  8. package/dist/lib/node/{chunk-MACQJ2EP.cjs.map → chunk-SXCQEIFA.cjs.map} +3 -3
  9. package/dist/lib/node/index.cjs +129 -87
  10. package/dist/lib/node/index.cjs.map +3 -3
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +10 -10
  13. package/dist/lib/node-esm/{chunk-JIZPSASG.mjs → chunk-ZIPZXXS7.mjs} +26 -8
  14. package/dist/lib/node-esm/{chunk-JIZPSASG.mjs.map → chunk-ZIPZXXS7.mjs.map} +3 -3
  15. package/dist/lib/node-esm/index.mjs +113 -64
  16. package/dist/lib/node-esm/index.mjs.map +3 -3
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +1 -1
  19. package/dist/types/src/automerge/automerge-host.d.ts +5 -1
  20. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  21. package/dist/types/src/automerge/collection-synchronizer.d.ts +1 -0
  22. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  23. package/dist/types/src/automerge/echo-network-adapter.d.ts +1 -0
  24. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  25. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +1 -1
  26. package/dist/types/src/db-host/echo-host.d.ts +3 -2
  27. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  28. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  29. package/dist/types/src/space/space-manager.d.ts +1 -0
  30. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +34 -34
  33. package/src/automerge/automerge-host.ts +49 -14
  34. package/src/automerge/collection-synchronizer.ts +8 -4
  35. package/src/automerge/echo-network-adapter.ts +7 -0
  36. package/src/automerge/mesh-echo-replicator.ts +2 -2
  37. package/src/db-host/echo-host.ts +4 -1
  38. package/src/edge/echo-edge-replicator.ts +47 -19
  39. package/src/space/space-manager.ts +17 -1
@@ -28,11 +28,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
- AuthExtension: () => import_chunk_MACQJ2EP.AuthExtension,
32
- AuthStatus: () => import_chunk_MACQJ2EP.AuthStatus,
31
+ AuthExtension: () => import_chunk_SXCQEIFA.AuthExtension,
32
+ AuthStatus: () => import_chunk_SXCQEIFA.AuthStatus,
33
33
  AutomergeHost: () => AutomergeHost,
34
- CredentialRetrieverExtension: () => import_chunk_MACQJ2EP.CredentialRetrieverExtension,
35
- CredentialServerExtension: () => import_chunk_MACQJ2EP.CredentialServerExtension,
34
+ CredentialRetrieverExtension: () => import_chunk_SXCQEIFA.CredentialRetrieverExtension,
35
+ CredentialServerExtension: () => import_chunk_SXCQEIFA.CredentialServerExtension,
36
36
  DataServiceImpl: () => DataServiceImpl,
37
37
  DatabaseRoot: () => DatabaseRoot,
38
38
  DocumentsSynchronizer: () => DocumentsSynchronizer,
@@ -40,37 +40,37 @@ __export(node_exports, {
40
40
  EchoEdgeReplicator: () => EchoEdgeReplicator,
41
41
  EchoHost: () => EchoHost,
42
42
  LevelDBStorageAdapter: () => LevelDBStorageAdapter,
43
- MOCK_AUTH_PROVIDER: () => import_chunk_MACQJ2EP.MOCK_AUTH_PROVIDER,
44
- MOCK_AUTH_VERIFIER: () => import_chunk_MACQJ2EP.MOCK_AUTH_VERIFIER,
43
+ MOCK_AUTH_PROVIDER: () => import_chunk_SXCQEIFA.MOCK_AUTH_PROVIDER,
44
+ MOCK_AUTH_VERIFIER: () => import_chunk_SXCQEIFA.MOCK_AUTH_VERIFIER,
45
45
  MeshEchoReplicator: () => MeshEchoReplicator,
46
- MetadataStore: () => import_chunk_MACQJ2EP.MetadataStore,
47
- Pipeline: () => import_chunk_MACQJ2EP.Pipeline,
46
+ MetadataStore: () => import_chunk_SXCQEIFA.MetadataStore,
47
+ Pipeline: () => import_chunk_SXCQEIFA.Pipeline,
48
48
  QueryServiceImpl: () => QueryServiceImpl,
49
49
  QueryState: () => QueryState,
50
- Space: () => import_chunk_MACQJ2EP.Space,
50
+ Space: () => import_chunk_SXCQEIFA.Space,
51
51
  SpaceDocumentListUpdatedEvent: () => SpaceDocumentListUpdatedEvent,
52
- SpaceManager: () => import_chunk_MACQJ2EP.SpaceManager,
53
- SpaceProtocol: () => import_chunk_MACQJ2EP.SpaceProtocol,
54
- SpaceProtocolSession: () => import_chunk_MACQJ2EP.SpaceProtocolSession,
52
+ SpaceManager: () => import_chunk_SXCQEIFA.SpaceManager,
53
+ SpaceProtocol: () => import_chunk_SXCQEIFA.SpaceProtocol,
54
+ SpaceProtocolSession: () => import_chunk_SXCQEIFA.SpaceProtocolSession,
55
55
  SpaceStateManager: () => SpaceStateManager,
56
- TimeframeClock: () => import_chunk_MACQJ2EP.TimeframeClock,
57
- codec: () => import_chunk_MACQJ2EP.codec,
58
- createIdFromSpaceKey: () => import_chunk_MACQJ2EP.createIdFromSpaceKey,
59
- createMappedFeedWriter: () => import_chunk_MACQJ2EP.createMappedFeedWriter,
56
+ TimeframeClock: () => import_chunk_SXCQEIFA.TimeframeClock,
57
+ codec: () => import_chunk_SXCQEIFA.codec,
58
+ createIdFromSpaceKey: () => import_chunk_SXCQEIFA.createIdFromSpaceKey,
59
+ createMappedFeedWriter: () => import_chunk_SXCQEIFA.createMappedFeedWriter,
60
60
  deriveCollectionIdFromSpaceId: () => deriveCollectionIdFromSpaceId,
61
61
  diffCollectionState: () => diffCollectionState,
62
62
  encodingOptions: () => encodingOptions,
63
63
  findInlineObjectOfType: () => findInlineObjectOfType,
64
64
  getSpaceIdFromCollectionId: () => getSpaceIdFromCollectionId,
65
65
  getSpaceKeyFromDoc: () => getSpaceKeyFromDoc,
66
- hasInvitationExpired: () => import_chunk_MACQJ2EP.hasInvitationExpired,
67
- mapFeedIndexesToTimeframe: () => import_chunk_MACQJ2EP.mapFeedIndexesToTimeframe,
68
- mapTimeframeToFeedIndexes: () => import_chunk_MACQJ2EP.mapTimeframeToFeedIndexes,
69
- startAfter: () => import_chunk_MACQJ2EP.startAfter,
70
- valueEncoding: () => import_chunk_MACQJ2EP.valueEncoding
66
+ hasInvitationExpired: () => import_chunk_SXCQEIFA.hasInvitationExpired,
67
+ mapFeedIndexesToTimeframe: () => import_chunk_SXCQEIFA.mapFeedIndexesToTimeframe,
68
+ mapTimeframeToFeedIndexes: () => import_chunk_SXCQEIFA.mapTimeframeToFeedIndexes,
69
+ startAfter: () => import_chunk_SXCQEIFA.startAfter,
70
+ valueEncoding: () => import_chunk_SXCQEIFA.valueEncoding
71
71
  });
72
72
  module.exports = __toCommonJS(node_exports);
73
- var import_chunk_MACQJ2EP = require("./chunk-MACQJ2EP.cjs");
73
+ var import_chunk_SXCQEIFA = require("./chunk-SXCQEIFA.cjs");
74
74
  var import_async = require("@dxos/async");
75
75
  var import_stream = require("@dxos/codec-protobuf/stream");
76
76
  var import_invariant = require("@dxos/invariant");
@@ -154,7 +154,6 @@ var import_invariant11 = require("@dxos/invariant");
154
154
  var A4 = __toESM(require("@dxos/automerge/automerge"));
155
155
  var import_log10 = require("@dxos/log");
156
156
  var import_async8 = require("@dxos/async");
157
- var A5 = __toESM(require("@dxos/automerge/automerge"));
158
157
  var import_automerge_repo5 = require("@dxos/automerge/automerge-repo");
159
158
  var import_context12 = require("@dxos/context");
160
159
  var import_crypto = require("@dxos/crypto");
@@ -418,7 +417,7 @@ var CollectionSynchronizer = class extends import_context3.Resource {
418
417
  return;
419
418
  }
420
419
  for (const [collectionId, state] of this._perCollectionStates.entries()) {
421
- if (this._shouldSyncCollection(collectionId, peerId)) {
420
+ if (this._activeCollections.has(collectionId) && this._shouldSyncCollection(collectionId, peerId)) {
422
421
  state.interestedPeers.add(peerId);
423
422
  state.lastQueried.set(peerId, Date.now());
424
423
  this._queryCollectionState(collectionId, peerId);
@@ -460,11 +459,18 @@ var CollectionSynchronizer = class extends import_context3.Resource {
460
459
  });
461
460
  validateCollectionState(state);
462
461
  const perCollectionState = this._getOrCreatePerCollectionState(collectionId);
463
- perCollectionState.remoteStates.set(peerId, state);
464
- this.remoteStateUpdated.emit({
465
- peerId,
466
- collectionId
467
- });
462
+ const existingState = perCollectionState.remoteStates.get(peerId) ?? {
463
+ documents: {}
464
+ };
465
+ const diff = diffCollectionState(existingState, state);
466
+ if (diff.missingOnLocal.length > 0 || diff.different.length > 0) {
467
+ perCollectionState.remoteStates.set(peerId, state);
468
+ this.remoteStateUpdated.emit({
469
+ peerId,
470
+ collectionId,
471
+ newDocsAppeared: diff.missingOnLocal.length > 0
472
+ });
473
+ }
468
474
  }
469
475
  _getOrCreatePerCollectionState(collectionId) {
470
476
  return (0, import_util.defaultMap)(this._perCollectionStates, collectionId, () => ({
@@ -616,7 +622,7 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
616
622
  getContainingSpaceForDocument: this._params.getContainingSpaceForDocument,
617
623
  getContainingSpaceIdForDocument: async (documentId) => {
618
624
  const key = await this._params.getContainingSpaceForDocument(documentId);
619
- return key ? (0, import_chunk_MACQJ2EP.createIdFromSpaceKey)(key) : null;
625
+ return key ? (0, import_chunk_SXCQEIFA.createIdFromSpaceKey)(key) : null;
620
626
  }
621
627
  });
622
628
  }
@@ -772,6 +778,12 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
772
778
  }
773
779
  this._params.monitor?.recordMessageReceived(message);
774
780
  }
781
+ onConnectionAuthScopeChanged(peer) {
782
+ const entry = this._connections.get(peer);
783
+ if (entry) {
784
+ this._onConnectionAuthScopeChanged(entry.connection);
785
+ }
786
+ }
775
787
  /**
776
788
  * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.
777
789
  * TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo
@@ -781,14 +793,14 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
781
793
  peerId: connection.peerId
782
794
  }, {
783
795
  F: __dxlog_file3,
784
- L: 254,
796
+ L: 261,
785
797
  S: this,
786
798
  C: (f, a) => f(...a)
787
799
  });
788
800
  const entry = this._connections.get(connection.peerId);
789
801
  (0, import_invariant4.invariant)(entry, void 0, {
790
802
  F: __dxlog_file3,
791
- L: 256,
803
+ L: 263,
792
804
  S: this,
793
805
  A: [
794
806
  "entry",
@@ -805,14 +817,14 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
805
817
  peerId: connection.peerId
806
818
  }, {
807
819
  F: __dxlog_file3,
808
- L: 262,
820
+ L: 269,
809
821
  S: this,
810
822
  C: (f, a) => f(...a)
811
823
  });
812
824
  const entry = this._connections.get(connection.peerId);
813
825
  (0, import_invariant4.invariant)(entry, void 0, {
814
826
  F: __dxlog_file3,
815
- L: 264,
827
+ L: 271,
816
828
  S: this,
817
829
  A: [
818
830
  "entry",
@@ -826,13 +838,13 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
826
838
  this._params.monitor?.recordPeerDisconnected(connection.peerId);
827
839
  void entry.reader.cancel().catch((err) => import_log5.log.catch(err, void 0, {
828
840
  F: __dxlog_file3,
829
- L: 270,
841
+ L: 277,
830
842
  S: this,
831
843
  C: (f, a) => f(...a)
832
844
  }));
833
845
  void entry.writer.abort().catch((err) => import_log5.log.catch(err, void 0, {
834
846
  F: __dxlog_file3,
835
- L: 271,
847
+ L: 278,
836
848
  S: this,
837
849
  C: (f, a) => f(...a)
838
850
  }));
@@ -992,7 +1004,7 @@ function _ts_decorate2(decorators, target, key, desc) {
992
1004
  }
993
1005
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
994
1006
  var AutomergeHost = class extends import_context2.Resource {
995
- constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider }) {
1007
+ constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
996
1008
  super();
997
1009
  this._collectionSynchronizer = new CollectionSynchronizer({
998
1010
  queryCollectionState: this._queryCollectionState.bind(this),
@@ -1021,6 +1033,7 @@ var AutomergeHost = class extends import_context2.Resource {
1021
1033
  });
1022
1034
  this._indexMetadataStore = indexMetadataStore;
1023
1035
  this._peerIdProvider = peerIdProvider;
1036
+ this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
1024
1037
  }
1025
1038
  async _open() {
1026
1039
  this._peerId = `host-${this._peerIdProvider?.() ?? import_keys2.PublicKey.random().toHex()}`;
@@ -1034,13 +1047,22 @@ var AutomergeHost = class extends import_context2.Resource {
1034
1047
  this._echoNetworkAdapter
1035
1048
  ]
1036
1049
  });
1037
- import_async3.Event.wrap(this._echoNetworkAdapter, "peer-candidate").on(this._ctx, (e) => this._onPeerConnected(e.peerId));
1038
- import_async3.Event.wrap(this._echoNetworkAdapter, "peer-disconnected").on(this._ctx, (e) => this._onPeerDisconnected(e.peerId));
1039
- this._collectionSynchronizer.remoteStateUpdated.on(this._ctx, ({ collectionId, peerId }) => {
1050
+ let updatingAuthScope = false;
1051
+ import_async3.Event.wrap(this._echoNetworkAdapter, "peer-candidate").on(this._ctx, (e) => !updatingAuthScope && this._onPeerConnected(e.peerId));
1052
+ import_async3.Event.wrap(this._echoNetworkAdapter, "peer-disconnected").on(this._ctx, (e) => !updatingAuthScope && this._onPeerDisconnected(e.peerId));
1053
+ this._collectionSynchronizer.remoteStateUpdated.on(this._ctx, ({ collectionId, peerId, newDocsAppeared }) => {
1040
1054
  this._onRemoteCollectionStateUpdated(collectionId, peerId);
1041
1055
  this.collectionStateUpdated.emit({
1042
1056
  collectionId
1043
1057
  });
1058
+ if (newDocsAppeared) {
1059
+ updatingAuthScope = true;
1060
+ try {
1061
+ this._echoNetworkAdapter.onConnectionAuthScopeChanged(peerId);
1062
+ } finally {
1063
+ updatingAuthScope = false;
1064
+ }
1065
+ }
1044
1066
  });
1045
1067
  await this._echoNetworkAdapter.open();
1046
1068
  await this._collectionSynchronizer.open();
@@ -1123,7 +1145,7 @@ var AutomergeHost = class extends import_context2.Resource {
1123
1145
  await Promise.all(headsToWait.map(async (entry, index) => {
1124
1146
  const handle = await this.loadDoc(import_context2.Context.default(void 0, {
1125
1147
  F: __dxlog_file4,
1126
- L: 239
1148
+ L: 264
1127
1149
  }), entry.documentId);
1128
1150
  await waitForHeads(handle, entry.heads);
1129
1151
  }));
@@ -1136,7 +1158,7 @@ var AutomergeHost = class extends import_context2.Resource {
1136
1158
  documentId
1137
1159
  }, {
1138
1160
  F: __dxlog_file4,
1139
- L: 251,
1161
+ L: 276,
1140
1162
  S: this,
1141
1163
  C: (f, a) => f(...a)
1142
1164
  });
@@ -1152,7 +1174,7 @@ var AutomergeHost = class extends import_context2.Resource {
1152
1174
  documentId
1153
1175
  }, {
1154
1176
  F: __dxlog_file4,
1155
- L: 255,
1177
+ L: 280,
1156
1178
  S: this,
1157
1179
  C: (f, a) => f(...a)
1158
1180
  });
@@ -1161,7 +1183,7 @@ var AutomergeHost = class extends import_context2.Resource {
1161
1183
  const doc = handle.docSync();
1162
1184
  (0, import_invariant3.invariant)(doc, void 0, {
1163
1185
  F: __dxlog_file4,
1164
- L: 260,
1186
+ L: 285,
1165
1187
  S: this,
1166
1188
  A: [
1167
1189
  "doc",
@@ -1175,7 +1197,7 @@ var AutomergeHost = class extends import_context2.Resource {
1175
1197
  }
1176
1198
  import_log3.log.info("done re-indexing heads", void 0, {
1177
1199
  F: __dxlog_file4,
1178
- L: 267,
1200
+ L: 292,
1179
1201
  S: this,
1180
1202
  C: (f, a) => f(...a)
1181
1203
  });
@@ -1259,14 +1281,17 @@ var AutomergeHost = class extends import_context2.Resource {
1259
1281
  }
1260
1282
  async _getContainingSpaceForDocument(documentId) {
1261
1283
  const doc = this._repo.handles[documentId]?.docSync();
1262
- if (!doc) {
1263
- return null;
1284
+ if (doc) {
1285
+ const spaceKeyHex = getSpaceKeyFromDoc(doc);
1286
+ if (spaceKeyHex) {
1287
+ return import_keys2.PublicKey.from(spaceKeyHex);
1288
+ }
1264
1289
  }
1265
- const spaceKeyHex = getSpaceKeyFromDoc(doc);
1266
- if (!spaceKeyHex) {
1267
- return null;
1290
+ const rootDocSpaceKey = this._getSpaceKeyByRootDocumentId?.(documentId);
1291
+ if (rootDocSpaceKey) {
1292
+ return rootDocSpaceKey;
1268
1293
  }
1269
- return import_keys2.PublicKey.from(spaceKeyHex);
1294
+ return null;
1270
1295
  }
1271
1296
  /**
1272
1297
  * Flush documents to disk.
@@ -1380,11 +1405,14 @@ var AutomergeHost = class extends import_context2.Resource {
1380
1405
  if (toReplicate.length === 0) {
1381
1406
  return;
1382
1407
  }
1383
- import_log3.log.info("replication documents after collection sync", {
1408
+ import_log3.log.info("replicating documents after collection sync", {
1409
+ collectionId,
1410
+ peerId,
1411
+ toReplicate,
1384
1412
  count: toReplicate.length
1385
1413
  }, {
1386
1414
  F: __dxlog_file4,
1387
- L: 499,
1415
+ L: 531,
1388
1416
  S: this,
1389
1417
  C: (f, a) => f(...a)
1390
1418
  });
@@ -1451,7 +1479,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
1451
1479
  var decodeCollectionState = (state) => {
1452
1480
  (0, import_invariant3.invariant)(typeof state === "object" && state !== null, "Invalid state", {
1453
1481
  F: __dxlog_file4,
1454
- L: 557,
1482
+ L: 592,
1455
1483
  S: void 0,
1456
1484
  A: [
1457
1485
  "typeof state === 'object' && state !== null",
@@ -1717,10 +1745,10 @@ var MeshEchoReplicator = class {
1717
1745
  documentId: params.documentId,
1718
1746
  peerId: connection.peerId
1719
1747
  });
1720
- (0, import_log6.log)("document not found locally for share policy check, accepting the remote document", {
1748
+ (0, import_log6.log)("document not found locally for share policy check", {
1721
1749
  peerId: connection.peerId,
1722
1750
  documentId: params.documentId,
1723
- remoteDocumentExists
1751
+ acceptDocument: remoteDocumentExists
1724
1752
  }, {
1725
1753
  F: __dxlog_file7,
1726
1754
  L: 91,
@@ -1729,7 +1757,7 @@ var MeshEchoReplicator = class {
1729
1757
  });
1730
1758
  return remoteDocumentExists;
1731
1759
  }
1732
- const spaceId = await (0, import_chunk_MACQJ2EP.createIdFromSpaceKey)(spaceKey);
1760
+ const spaceId = await (0, import_chunk_SXCQEIFA.createIdFromSpaceKey)(spaceKey);
1733
1761
  const authorizedDevices = this._authorizedDevices.get(spaceId);
1734
1762
  if (!connection.remoteDeviceKey) {
1735
1763
  (0, import_log6.log)("device key not found for share policy check", {
@@ -1800,7 +1828,7 @@ var MeshEchoReplicator = class {
1800
1828
  S: this,
1801
1829
  C: (f, a) => f(...a)
1802
1830
  });
1803
- const spaceId = await (0, import_chunk_MACQJ2EP.createIdFromSpaceKey)(spaceKey);
1831
+ const spaceId = await (0, import_chunk_SXCQEIFA.createIdFromSpaceKey)(spaceKey);
1804
1832
  (0, import_util3.defaultMap)(this._authorizedDevices, spaceId, () => new import_util3.ComplexSet(import_keys3.PublicKey.hash)).add(deviceKey);
1805
1833
  for (const connection of this._connections) {
1806
1834
  if (connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
@@ -2917,7 +2945,7 @@ var INDEXER_CONFIG = {
2917
2945
  ]
2918
2946
  };
2919
2947
  var EchoHost = class extends import_context7.Resource {
2920
- constructor({ kv, peerIdProvider }) {
2948
+ constructor({ kv, peerIdProvider, getSpaceKeyByRootDocumentId }) {
2921
2949
  super();
2922
2950
  this._spaceStateManager = new SpaceStateManager();
2923
2951
  this._indexMetadataStore = new import_indexing2.IndexMetadataStore({
@@ -2928,7 +2956,8 @@ var EchoHost = class extends import_context7.Resource {
2928
2956
  db: kv,
2929
2957
  dataMonitor: this._echoDataMonitor,
2930
2958
  indexMetadataStore: this._indexMetadataStore,
2931
- peerIdProvider
2959
+ peerIdProvider,
2960
+ getSpaceKeyByRootDocumentId
2932
2961
  });
2933
2962
  this._indexer = new import_indexing2.Indexer({
2934
2963
  db: kv,
@@ -3053,7 +3082,7 @@ var EchoHost = class extends import_context7.Resource {
3053
3082
  async createSpaceRoot(spaceKey) {
3054
3083
  (0, import_invariant8.invariant)(this._lifecycleState === import_context7.LifecycleState.OPEN, void 0, {
3055
3084
  F: __dxlog_file15,
3056
- L: 217,
3085
+ L: 220,
3057
3086
  S: this,
3058
3087
  A: [
3059
3088
  "this._lifecycleState === LifecycleState.OPEN",
@@ -3081,7 +3110,7 @@ var EchoHost = class extends import_context7.Resource {
3081
3110
  async openSpaceRoot(spaceId, automergeUrl) {
3082
3111
  (0, import_invariant8.invariant)(this._lifecycleState === import_context7.LifecycleState.OPEN, void 0, {
3083
3112
  F: __dxlog_file15,
3084
- L: 236,
3113
+ L: 239,
3085
3114
  S: this,
3086
3115
  A: [
3087
3116
  "this._lifecycleState === LifecycleState.OPEN",
@@ -3191,14 +3220,14 @@ var EchoEdgeReplicator = class {
3191
3220
  connectedSpaces: this._connectedSpaces.size
3192
3221
  }, {
3193
3222
  F: __dxlog_file16,
3194
- L: 60,
3223
+ L: 59,
3195
3224
  S: this,
3196
3225
  C: (f, a) => f(...a)
3197
3226
  });
3198
3227
  this._context = context;
3199
3228
  this._ctx = import_context12.Context.default(void 0, {
3200
3229
  F: __dxlog_file16,
3201
- L: 63
3230
+ L: 62
3202
3231
  });
3203
3232
  this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
3204
3233
  this._ctx && (0, import_async8.scheduleMicroTask)(this._ctx, () => this._handleReconnect());
@@ -3277,7 +3306,7 @@ var EchoEdgeReplicator = class {
3277
3306
  async _openConnection(spaceId, reconnects = 0) {
3278
3307
  (0, import_invariant12.invariant)(this._context, void 0, {
3279
3308
  F: __dxlog_file16,
3280
- L: 124,
3309
+ L: 123,
3281
3310
  S: this,
3282
3311
  A: [
3283
3312
  "this._context",
@@ -3286,7 +3315,7 @@ var EchoEdgeReplicator = class {
3286
3315
  });
3287
3316
  (0, import_invariant12.invariant)(!this._connections.has(spaceId), void 0, {
3288
3317
  F: __dxlog_file16,
3289
- L: 125,
3318
+ L: 124,
3290
3319
  S: this,
3291
3320
  A: [
3292
3321
  "!this._connections.has(spaceId)",
@@ -3316,7 +3345,7 @@ var EchoEdgeReplicator = class {
3316
3345
  restartDelay
3317
3346
  }, {
3318
3347
  F: __dxlog_file16,
3319
- L: 148,
3348
+ L: 147,
3320
3349
  S: this,
3321
3350
  C: (f, a) => f(...a)
3322
3351
  });
@@ -3347,10 +3376,13 @@ var EchoEdgeReplicator = class {
3347
3376
  await connection.open();
3348
3377
  }
3349
3378
  };
3379
+ var MAX_INFLIGHT_REQUESTS = 5;
3350
3380
  var EdgeReplicatorConnection = class extends import_context12.Resource {
3351
3381
  constructor({ edgeConnection, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
3352
3382
  super();
3353
3383
  this._remotePeerId = null;
3384
+ this._outgoingRequestsBarrier = new import_async8.Trigger();
3385
+ this._inflightRequests = 0;
3354
3386
  this._edgeConnection = edgeConnection;
3355
3387
  this._spaceId = spaceId;
3356
3388
  this._context = context;
@@ -3360,6 +3392,7 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3360
3392
  this._onRemoteConnected = onRemoteConnected;
3361
3393
  this._onRemoteDisconnected = onRemoteDisconnected;
3362
3394
  this._onRestartRequested = onRestartRequested;
3395
+ this._outgoingRequestsBarrier.wake();
3363
3396
  this.readable = new ReadableStream({
3364
3397
  start: (controller) => {
3365
3398
  this._readableStreamController = controller;
@@ -3367,6 +3400,11 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3367
3400
  });
3368
3401
  this.writable = new WritableStream({
3369
3402
  write: async (message, controller) => {
3403
+ await this._outgoingRequestsBarrier.wait();
3404
+ this._inflightRequests++;
3405
+ if (this._inflightRequests === MAX_INFLIGHT_REQUESTS) {
3406
+ this._outgoingRequestsBarrier.reset();
3407
+ }
3370
3408
  await this._sendMessage(message);
3371
3409
  }
3372
3410
  });
@@ -3374,7 +3412,7 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3374
3412
  async _open(ctx) {
3375
3413
  (0, import_log11.log)("open", void 0, {
3376
3414
  F: __dxlog_file16,
3377
- L: 242,
3415
+ L: 261,
3378
3416
  S: this,
3379
3417
  C: (f, a) => f(...a)
3380
3418
  });
@@ -3386,17 +3424,18 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3386
3424
  async _close() {
3387
3425
  (0, import_log11.log)("close", void 0, {
3388
3426
  F: __dxlog_file16,
3389
- L: 254,
3427
+ L: 273,
3390
3428
  S: this,
3391
3429
  C: (f, a) => f(...a)
3392
3430
  });
3393
3431
  this._readableStreamController.close();
3432
+ this._outgoingRequestsBarrier.throw(new Error("Connection closed."));
3394
3433
  await this._onRemoteDisconnected();
3395
3434
  }
3396
3435
  get peerId() {
3397
3436
  (0, import_invariant12.invariant)(this._remotePeerId, "Not connected", {
3398
3437
  F: __dxlog_file16,
3399
- L: 260,
3438
+ L: 282,
3400
3439
  S: this,
3401
3440
  A: [
3402
3441
  "this._remotePeerId",
@@ -3415,12 +3454,13 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3415
3454
  documentId: params.documentId,
3416
3455
  peerId: this._remotePeerId
3417
3456
  });
3418
- import_log11.log.info("document not found locally for share policy check, accepting the remote document", {
3457
+ import_log11.log.verbose("edge-replicator document not found locally for share policy check", {
3419
3458
  documentId: params.documentId,
3420
- remoteDocumentExists
3459
+ acceptDocument: remoteDocumentExists,
3460
+ remoteId: this._remotePeerId
3421
3461
  }, {
3422
3462
  F: __dxlog_file16,
3423
- L: 275,
3463
+ L: 297,
3424
3464
  S: this,
3425
3465
  C: (f, a) => f(...a)
3426
3466
  });
@@ -3433,23 +3473,20 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3433
3473
  return true;
3434
3474
  }
3435
3475
  const spaceId = getSpaceIdFromCollectionId(params.collectionId);
3436
- return spaceId === this._spaceId;
3476
+ return spaceId === this._spaceId && params.collectionId.split(":").length === 3;
3437
3477
  }
3438
3478
  _onMessage(message) {
3439
3479
  if (message.serviceId !== this._targetServiceId) {
3440
3480
  return;
3441
3481
  }
3442
3482
  const payload = import_automerge_repo5.cbor.decode(message.payload.value);
3443
- (0, import_log11.log)("recv", () => {
3444
- const decodedData = payload.type === "sync" && payload.data ? A5.decodeSyncMessage(payload.data) : payload.type === "collection-state" ? payload.state : payload;
3445
- return {
3446
- from: message.serviceId,
3447
- type: payload.type,
3448
- decodedData
3449
- };
3483
+ import_log11.log.verbose("edge replicator receive", {
3484
+ type: payload.type,
3485
+ documentId: payload.type === "sync" && payload.documentId,
3486
+ remoteId: this._remotePeerId
3450
3487
  }, {
3451
3488
  F: __dxlog_file16,
3452
- L: 302,
3489
+ L: 326,
3453
3490
  S: this,
3454
3491
  C: (f, a) => f(...a)
3455
3492
  });
@@ -3461,18 +3498,23 @@ var EdgeReplicatorConnection = class extends import_context12.Resource {
3461
3498
  this._onRestartRequested();
3462
3499
  return;
3463
3500
  }
3501
+ if (message.type === "sync") {
3502
+ this._inflightRequests--;
3503
+ if (this._inflightRequests === MAX_INFLIGHT_REQUESTS - 1) {
3504
+ this._outgoingRequestsBarrier.wake();
3505
+ }
3506
+ }
3464
3507
  this._readableStreamController.enqueue(message);
3465
3508
  }
3466
3509
  async _sendMessage(message) {
3467
3510
  message.targetId = this._targetServiceId;
3468
- (0, import_log11.log)("send", {
3511
+ import_log11.log.verbose("edge replicator send", {
3469
3512
  type: message.type,
3470
- senderId: message.senderId,
3471
- targetId: message.targetId,
3472
- documentId: message.documentId
3513
+ documentId: message.type === "sync" && message.documentId,
3514
+ remoteId: this._remotePeerId
3473
3515
  }, {
3474
3516
  F: __dxlog_file16,
3475
- L: 332,
3517
+ L: 360,
3476
3518
  S: this,
3477
3519
  C: (f, a) => f(...a)
3478
3520
  });