@dxos/echo-pipeline 0.5.9-main.d63ef8d → 0.5.9-main.d787c80

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.
@@ -32,7 +32,6 @@ import { Repo } from "@dxos/automerge/automerge-repo";
32
32
  import { Context } from "@dxos/context";
33
33
  import { invariant as invariant3 } from "@dxos/invariant";
34
34
  import { PublicKey } from "@dxos/keys";
35
- import { log as log2 } from "@dxos/log";
36
35
  import { objectPointerCodec } from "@dxos/protocols";
37
36
  import { trace } from "@dxos/tracing";
38
37
  import { mapValues } from "@dxos/util";
@@ -591,7 +590,6 @@ var AutomergeHost = class {
591
590
  this._echoNetworkAdapter = new EchoNetworkAdapter({
592
591
  getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this)
593
592
  });
594
- this._requestedDocs = /* @__PURE__ */ new Set();
595
593
  this._storage = new LevelDBStorageAdapter({
596
594
  db,
597
595
  callbacks: {
@@ -647,21 +645,6 @@ var AutomergeHost = class {
647
645
  if (!documentId) {
648
646
  return false;
649
647
  }
650
- const doc = this._repo.handles[documentId]?.docSync();
651
- if (!doc) {
652
- const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
653
- log2("doc share policy check", {
654
- peerId,
655
- documentId,
656
- isRequested
657
- }, {
658
- F: __dxlog_file3,
659
- L: 143,
660
- S: this,
661
- C: (f, a) => f(...a)
662
- });
663
- return isRequested;
664
- }
665
648
  const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
666
649
  if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
667
650
  return this._echoNetworkAdapter.shouldAdvertize(peerId, {
@@ -742,7 +725,7 @@ var AutomergeHost = class {
742
725
  await Promise.all(states?.map(async ({ heads, documentId }) => {
743
726
  invariant3(heads, "heads are required for flush", {
744
727
  F: __dxlog_file3,
745
- L: 237,
728
+ L: 223,
746
729
  S: this,
747
730
  A: [
748
731
  "heads",
@@ -817,7 +800,7 @@ import { cancelWithContext } from "@dxos/context";
817
800
  import { warnAfterTimeout } from "@dxos/debug";
818
801
  import { SpaceDocVersion } from "@dxos/echo-protocol";
819
802
  import { invariant as invariant4 } from "@dxos/invariant";
820
- import { log as log3 } from "@dxos/log";
803
+ import { log as log2 } from "@dxos/log";
821
804
  import { trace as trace2 } from "@dxos/tracing";
822
805
  function _ts_decorate3(decorators, target, key, desc) {
823
806
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -851,7 +834,7 @@ var AutomergeDocumentLoaderImpl = class {
851
834
  return;
852
835
  }
853
836
  if (!spaceState.rootUrl) {
854
- log3.error("Database opened with no rootUrl", {
837
+ log2.error("Database opened with no rootUrl", {
855
838
  spaceId: this._spaceId
856
839
  }, {
857
840
  F: __dxlog_file4,
@@ -910,7 +893,7 @@ var AutomergeDocumentLoaderImpl = class {
910
893
  const documentUrl = (spaceRootDoc.links ?? {})[objectId];
911
894
  if (documentUrl == null) {
912
895
  this._objectsPendingDocumentLoad.add(objectId);
913
- log3.info("loading delayed until object links are initialized", {
896
+ log2.info("loading delayed until object links are initialized", {
914
897
  objectId
915
898
  }, {
916
899
  F: __dxlog_file4,
@@ -990,7 +973,7 @@ var AutomergeDocumentLoaderImpl = class {
990
973
  };
991
974
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
992
975
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
993
- log3.warn("object already inlined in a different document, ignoring the link", {
976
+ log2.warn("object already inlined in a different document, ignoring the link", {
994
977
  ...logMeta,
995
978
  actualDocumentUrl: objectDocumentHandle.url
996
979
  }, {
@@ -1002,7 +985,7 @@ var AutomergeDocumentLoaderImpl = class {
1002
985
  continue;
1003
986
  }
1004
987
  if (objectDocumentHandle?.url === automergeUrl) {
1005
- log3.warn("object document was already loaded", logMeta, {
988
+ log2.warn("object document was already loaded", logMeta, {
1006
989
  F: __dxlog_file4,
1007
990
  L: 166,
1008
991
  S: this,
@@ -1011,7 +994,7 @@ var AutomergeDocumentLoaderImpl = class {
1011
994
  continue;
1012
995
  }
1013
996
  const handle = this._repo.find(automergeUrl);
1014
- log3.debug("document loading triggered", logMeta, {
997
+ log2.debug("document loading triggered", logMeta, {
1015
998
  F: __dxlog_file4,
1016
999
  L: 170,
1017
1000
  S: this,
@@ -1031,7 +1014,7 @@ var AutomergeDocumentLoaderImpl = class {
1031
1014
  break;
1032
1015
  } catch (err) {
1033
1016
  if (`${err}`.includes("Timeout")) {
1034
- log3.info("wraparound", {
1017
+ log2.info("wraparound", {
1035
1018
  id: docHandle.documentId,
1036
1019
  state: docHandle.state
1037
1020
  }, {
@@ -1076,7 +1059,7 @@ var AutomergeDocumentLoaderImpl = class {
1076
1059
  docUrl: handle.url
1077
1060
  };
1078
1061
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
1079
- log3.info("document loaded after all listeners were removed", logMeta, {
1062
+ log2.info("document loaded after all listeners were removed", logMeta, {
1080
1063
  F: __dxlog_file4,
1081
1064
  L: 222,
1082
1065
  S: this,
@@ -1086,7 +1069,7 @@ var AutomergeDocumentLoaderImpl = class {
1086
1069
  }
1087
1070
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
1088
1071
  if (objectDocHandle?.url !== handle.url) {
1089
- log3.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1072
+ log2.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1090
1073
  F: __dxlog_file4,
1091
1074
  L: 227,
1092
1075
  S: this,
@@ -1100,7 +1083,7 @@ var AutomergeDocumentLoaderImpl = class {
1100
1083
  });
1101
1084
  } catch (err) {
1102
1085
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1103
- log3.warn("failed to load a document", {
1086
+ log2.warn("failed to load a document", {
1104
1087
  objectId,
1105
1088
  automergeUrl: handle.url,
1106
1089
  retryLoading: shouldRetryLoading,
@@ -1131,7 +1114,7 @@ import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
1131
1114
  import { Resource as Resource2 } from "@dxos/context";
1132
1115
  import { invariant as invariant5 } from "@dxos/invariant";
1133
1116
  import { PublicKey as PublicKey2 } from "@dxos/keys";
1134
- import { log as log4 } from "@dxos/log";
1117
+ import { log as log3 } from "@dxos/log";
1135
1118
  import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
1136
1119
  import { ComplexMap, ComplexSet, defaultMap } from "@dxos/util";
1137
1120
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
@@ -1172,7 +1155,7 @@ var MeshEchoReplicator = class {
1172
1155
  const connection = new MeshReplicatorConnection({
1173
1156
  ownPeerId: this._context.peerId,
1174
1157
  onRemoteConnected: async () => {
1175
- log4("onRemoteConnected", {
1158
+ log3("onRemoteConnected", {
1176
1159
  peerId: connection.peerId
1177
1160
  }, {
1178
1161
  F: __dxlog_file5,
@@ -1198,7 +1181,7 @@ var MeshEchoReplicator = class {
1198
1181
  }
1199
1182
  },
1200
1183
  onRemoteDisconnected: async () => {
1201
- log4("onRemoteDisconnected", {
1184
+ log3("onRemoteDisconnected", {
1202
1185
  peerId: connection.peerId
1203
1186
  }, {
1204
1187
  F: __dxlog_file5,
@@ -1212,7 +1195,7 @@ var MeshEchoReplicator = class {
1212
1195
  this._connections.delete(connection);
1213
1196
  },
1214
1197
  shouldAdvertize: async (params) => {
1215
- log4("shouldAdvertize", {
1198
+ log3("shouldAdvertize", {
1216
1199
  peerId: connection.peerId,
1217
1200
  documentId: params.documentId
1218
1201
  }, {
@@ -1233,7 +1216,7 @@ var MeshEchoReplicator = class {
1233
1216
  try {
1234
1217
  const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
1235
1218
  if (!spaceKey) {
1236
- log4("space key not found for share policy check", {
1219
+ log3("space key not found for share policy check", {
1237
1220
  peerId: connection.peerId,
1238
1221
  documentId: params.documentId
1239
1222
  }, {
@@ -1246,7 +1229,7 @@ var MeshEchoReplicator = class {
1246
1229
  }
1247
1230
  const authorizedDevices = this._authorizedDevices.get(spaceKey);
1248
1231
  if (!connection.remoteDeviceKey) {
1249
- log4("device key not found for share policy check", {
1232
+ log3("device key not found for share policy check", {
1250
1233
  peerId: connection.peerId,
1251
1234
  documentId: params.documentId
1252
1235
  }, {
@@ -1258,7 +1241,7 @@ var MeshEchoReplicator = class {
1258
1241
  return false;
1259
1242
  }
1260
1243
  const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
1261
- log4("share policy check", {
1244
+ log3("share policy check", {
1262
1245
  localPeer: this._context.peerId,
1263
1246
  remotePeer: connection.peerId,
1264
1247
  documentId: params.documentId,
@@ -1273,7 +1256,7 @@ var MeshEchoReplicator = class {
1273
1256
  });
1274
1257
  return isAuthorized;
1275
1258
  } catch (err) {
1276
- log4.catch(err, void 0, {
1259
+ log3.catch(err, void 0, {
1277
1260
  F: __dxlog_file5,
1278
1261
  L: 111,
1279
1262
  S: this,
@@ -1287,7 +1270,7 @@ var MeshEchoReplicator = class {
1287
1270
  return connection.replicatorExtension;
1288
1271
  }
1289
1272
  authorizeDevice(spaceKey, deviceKey) {
1290
- log4("authorizeDevice", {
1273
+ log3("authorizeDevice", {
1291
1274
  spaceKey,
1292
1275
  deviceKey
1293
1276
  }, {
@@ -1297,6 +1280,11 @@ var MeshEchoReplicator = class {
1297
1280
  C: (f, a) => f(...a)
1298
1281
  });
1299
1282
  defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey2.hash)).add(deviceKey);
1283
+ for (const connection of this._connections) {
1284
+ if (connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
1285
+ this._context?.onConnectionAuthScopeChanged(connection);
1286
+ }
1287
+ }
1300
1288
  }
1301
1289
  };
1302
1290
  var MeshReplicatorConnection = class extends Resource2 {
@@ -1328,13 +1316,13 @@ var MeshReplicatorConnection = class extends Resource2 {
1328
1316
  onStartReplication: async (info, remotePeerId) => {
1329
1317
  this.remoteDeviceKey = remotePeerId;
1330
1318
  this._remotePeerId = info.id;
1331
- log4("onStartReplication", {
1319
+ log3("onStartReplication", {
1332
1320
  id: info.id,
1333
1321
  thisPeerId: this.peerId,
1334
1322
  remotePeerId: remotePeerId.toHex()
1335
1323
  }, {
1336
1324
  F: __dxlog_file5,
1337
- L: 187,
1325
+ L: 192,
1338
1326
  S: this,
1339
1327
  C: (f, a) => f(...a)
1340
1328
  });
@@ -1358,7 +1346,7 @@ var MeshReplicatorConnection = class extends Resource2 {
1358
1346
  get peerId() {
1359
1347
  invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1360
1348
  F: __dxlog_file5,
1361
- L: 210,
1349
+ L: 215,
1362
1350
  S: this,
1363
1351
  A: [
1364
1352
  "this._remotePeerId != null",
@@ -1377,7 +1365,7 @@ var MeshReplicatorConnection = class extends Resource2 {
1377
1365
  async enable() {
1378
1366
  invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1379
1367
  F: __dxlog_file5,
1380
- L: 223,
1368
+ L: 228,
1381
1369
  S: this,
1382
1370
  A: [
1383
1371
  "this._remotePeerId != null",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/automerge/automerge-host.ts", "../../../src/automerge/echo-network-adapter.ts", "../../../src/automerge/leveldb-storage-adapter.ts", "../../../src/automerge/local-host-network-adapter.ts", "../../../src/automerge/automerge-doc-loader.ts", "../../../src/automerge/mesh-echo-replicator.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { next as automerge, getBackend, getHeads, type Doc, type Heads } from '@dxos/automerge/automerge';\nimport {\n Repo,\n type DocHandle,\n type DocHandleChangePayload,\n type DocumentId,\n type PeerId,\n type StorageAdapterInterface,\n} from '@dxos/automerge/automerge-repo';\nimport { type Stream } from '@dxos/codec-protobuf';\nimport { Context, type Lifecycle } from '@dxos/context';\nimport { type SpaceDoc } from '@dxos/echo-protocol';\nimport { type IndexMetadataStore } from '@dxos/indexing';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { type SublevelDB } from '@dxos/kv-store';\nimport { log } from '@dxos/log';\nimport { objectPointerCodec } from '@dxos/protocols';\nimport {\n type FlushRequest,\n type HostInfo,\n type SyncRepoRequest,\n type SyncRepoResponse,\n} from '@dxos/protocols/proto/dxos/echo/service';\nimport { trace } from '@dxos/tracing';\nimport { mapValues } from '@dxos/util';\n\nimport { EchoNetworkAdapter } from './echo-network-adapter';\nimport { type EchoReplicator } from './echo-replicator';\nimport { LevelDBStorageAdapter, type BeforeSaveParams } from './leveldb-storage-adapter';\nimport { LocalHostNetworkAdapter } from './local-host-network-adapter';\n\n// TODO: Remove\nexport type { DocumentId };\n\nexport type AutomergeHostParams = {\n db: SublevelDB;\n\n indexMetadataStore: IndexMetadataStore;\n};\n\n@trace.resource()\nexport class AutomergeHost {\n private readonly _indexMetadataStore: IndexMetadataStore;\n private readonly _ctx = new Context();\n private readonly _echoNetworkAdapter = new EchoNetworkAdapter({\n getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),\n });\n\n private _repo!: Repo;\n private _clientNetwork!: LocalHostNetworkAdapter;\n private _storage!: StorageAdapterInterface & Lifecycle;\n\n @trace.info()\n private _peerId!: string;\n\n public _requestedDocs = new Set<string>();\n\n constructor({ db, indexMetadataStore }: AutomergeHostParams) {\n this._storage = new LevelDBStorageAdapter({\n db,\n callbacks: {\n beforeSave: async (params) => this._beforeSave(params),\n afterSave: async () => this._afterSave(),\n },\n });\n this._indexMetadataStore = indexMetadataStore;\n }\n\n async open() {\n // TODO(burdon): Should this be stable?\n this._peerId = `host-${PublicKey.random().toHex()}` as PeerId;\n\n await this._storage.open?.();\n this._clientNetwork = new LocalHostNetworkAdapter();\n\n // Construct the automerge repo.\n this._repo = new Repo({\n peerId: this._peerId as PeerId,\n sharePolicy: this._sharePolicy.bind(this),\n storage: this._storage,\n network: [\n // Downstream client.\n this._clientNetwork,\n // Upstream swarm.\n this._echoNetworkAdapter,\n ],\n });\n\n this._clientNetwork.ready();\n await this._echoNetworkAdapter.open();\n await this._clientNetwork.whenConnected();\n await this._echoNetworkAdapter.whenConnected();\n }\n\n async close() {\n await this._storage.close?.();\n await this._clientNetwork.close();\n await this._echoNetworkAdapter.close();\n await this._ctx.dispose();\n }\n\n get repo(): Repo {\n return this._repo;\n }\n\n async addReplicator(replicator: EchoReplicator) {\n await this._echoNetworkAdapter.addReplicator(replicator);\n }\n\n async removeReplicator(replicator: EchoReplicator) {\n await this._echoNetworkAdapter.removeReplicator(replicator);\n }\n\n // TODO(dmaretskyi): Share based on HALO permissions and space affinity.\n // Hosts, running in the worker, don't share documents unless requested by other peers.\n // NOTE: If both peers return sharePolicy=false the replication will not happen\n // https://github.com/automerge/automerge-repo/pull/292\n private async _sharePolicy(\n peerId: PeerId /* device key */,\n documentId?: DocumentId /* space key */,\n ): Promise<boolean> {\n if (peerId.startsWith('client-')) {\n return false; // Only send docs to clients if they are requested.\n }\n\n if (!documentId) {\n return false;\n }\n\n // Workaround for https://github.com/automerge/automerge-repo/pull/292\n // NOTE: This must override the per-connection policy.\n const doc = this._repo.handles[documentId]?.docSync();\n if (!doc) {\n // TODO(dmaretskyi): Verify that this works as intended.\n // TODO(dmaretskyi): Move to MESH replicator?\n const isRequested = this._requestedDocs.has(`automerge:${documentId}`);\n log('doc share policy check', { peerId, documentId, isRequested });\n return isRequested;\n }\n\n const peerMetadata = this.repo.peerMetadataByPeerId[peerId];\n if ((peerMetadata as any)?.dxos_peerSource === 'EchoNetworkAdapter') {\n return this._echoNetworkAdapter.shouldAdvertize(peerId, { documentId });\n }\n\n return false;\n }\n\n private async _beforeSave({ path, batch }: BeforeSaveParams) {\n const handle = this._repo.handles[path[0] as DocumentId];\n if (!handle) {\n return;\n }\n const doc = handle.docSync();\n if (!doc) {\n return;\n }\n\n const spaceKey = getSpaceKeyFromDoc(doc) ?? undefined;\n\n const lastAvailableHash = getHeads(doc);\n\n const objectIds = Object.keys(doc.objects ?? {});\n const encodedIds = objectIds.map((objectId) =>\n objectPointerCodec.encode({ documentId: handle.documentId, objectId, spaceKey }),\n );\n const idToLastHash = new Map(encodedIds.map((id) => [id, lastAvailableHash]));\n this._indexMetadataStore.markDirty(idToLastHash, batch);\n }\n\n /**\n * Called by AutomergeStorageAdapter after levelDB batch commit.\n */\n private async _afterSave() {\n this._indexMetadataStore.notifyMarkedDirty();\n }\n\n @trace.info({ depth: null })\n private _automergeDocs() {\n return mapValues(this._repo.handles, (handle) => ({\n state: handle.state,\n hasDoc: !!handle.docSync(),\n heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,\n data:\n handle.docSync() &&\n mapValues(handle.docSync(), (value, key) => {\n try {\n switch (key) {\n case 'access':\n case 'links':\n return value;\n case 'objects':\n return Object.keys(value as any);\n default:\n return `${value}`;\n }\n } catch (err) {\n return `${err}`;\n }\n }),\n }));\n }\n\n @trace.info({ depth: null })\n private _automergePeers() {\n return this._repo.peers;\n }\n\n private async _getContainingSpaceForDocument(documentId: string): Promise<PublicKey | null> {\n const doc = this._repo.handles[documentId as any]?.docSync();\n if (!doc) {\n return null;\n }\n\n const spaceKeyHex = getSpaceKeyFromDoc(doc);\n if (!spaceKeyHex) {\n return null;\n }\n\n return PublicKey.from(spaceKeyHex);\n }\n\n //\n // Methods for client-services.\n //\n @trace.span({ showInBrowserTimeline: true })\n async flush({ states }: FlushRequest): Promise<void> {\n // Note: Wait for all requested documents to be loaded/synced from thin-client.\n await Promise.all(\n states?.map(async ({ heads, documentId }) => {\n invariant(heads, 'heads are required for flush');\n const handle = this.repo.handles[documentId as DocumentId] ?? this._repo.find(documentId as DocumentId);\n await waitForHeads(handle, heads);\n }) ?? [],\n );\n\n await this._repo.flush(states?.map(({ documentId }) => documentId as DocumentId));\n }\n\n syncRepo(request: SyncRepoRequest): Stream<SyncRepoResponse> {\n return this._clientNetwork.syncRepo(request);\n }\n\n sendSyncMessage(request: SyncRepoRequest): Promise<void> {\n return this._clientNetwork.sendSyncMessage(request);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n return this._clientNetwork.getHostInfo();\n }\n}\n\nexport const getSpaceKeyFromDoc = (doc: any): string | null => {\n // experimental_spaceKey is set on old documents, new ones are created with doc.access.spaceKey\n const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;\n if (rawSpaceKey == null) {\n return null;\n }\n\n return String(rawSpaceKey);\n};\n\nconst waitForHeads = async (handle: DocHandle<SpaceDoc>, heads: Heads) => {\n await handle.whenReady();\n const unavailableHeads = new Set(heads);\n\n await Event.wrap<DocHandleChangePayload<SpaceDoc>>(handle, 'change').waitForCondition(() => {\n // Check if unavailable heads became available.\n for (const changeHash of unavailableHeads.values()) {\n if (changeIsPresentInDoc(handle.docSync(), changeHash)) {\n unavailableHeads.delete(changeHash);\n }\n }\n\n if (unavailableHeads.size === 0) {\n return true;\n }\n return false;\n });\n};\n\nconst changeIsPresentInDoc = (doc: Doc<any>, changeHash: string): boolean => {\n return !!getBackend(doc).getChangeByHash(changeHash);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger, synchronized } from '@dxos/async';\nimport { type Message, NetworkAdapter, type PeerId, type PeerMetadata } from '@dxos/automerge/automerge-repo';\nimport { LifecycleState } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type EchoReplicator, type ReplicatorConnection, type ShouldAdvertizeParams } from './echo-replicator';\n\nexport type EchoNetworkAdapterParams = {\n getContainingSpaceForDocument: (documentId: string) => Promise<PublicKey | null>;\n};\n\n/**\n * Manages a set of {@link EchoReplicator} instances.\n */\nexport class EchoNetworkAdapter extends NetworkAdapter {\n private readonly _replicators = new Set<EchoReplicator>();\n /**\n * Remote peer id -> connection.\n */\n private readonly _connections = new Map<PeerId, ConnectionEntry>();\n private _lifecycleState: LifecycleState = LifecycleState.CLOSED;\n private readonly _connected = new Trigger();\n\n constructor(private readonly _params: EchoNetworkAdapterParams) {\n super();\n }\n\n override connect(peerId: PeerId, peerMetadata?: PeerMetadata | undefined): void {\n this.peerId = peerId;\n this.peerMetadata = peerMetadata;\n this._connected.wake();\n }\n\n override send(message: Message): void {\n const connectionEntry = this._connections.get(message.targetId);\n if (!connectionEntry) {\n throw new Error('Connection not found.');\n }\n\n // TODO(dmaretskyi): Find a way to enforce backpressure on AM-repo.\n connectionEntry.writer.write(message).catch((err) => {\n if (connectionEntry.isOpen) {\n log.catch(err);\n }\n });\n }\n\n override disconnect(): void {\n // No-op\n }\n\n @synchronized\n async open() {\n invariant(this._lifecycleState === LifecycleState.CLOSED);\n this._lifecycleState = LifecycleState.OPEN;\n\n log('emit ready');\n this.emit('ready', {\n network: this,\n });\n }\n\n @synchronized\n async close() {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n\n for (const replicator of this._replicators) {\n await replicator.disconnect();\n }\n this._replicators.clear();\n\n this._lifecycleState = LifecycleState.CLOSED;\n }\n\n async whenConnected() {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n @synchronized\n async addReplicator(replicator: EchoReplicator) {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n invariant(this.peerId);\n invariant(!this._replicators.has(replicator));\n\n this._replicators.add(replicator);\n await replicator.connect({\n peerId: this.peerId,\n onConnectionOpen: this._onConnectionOpen.bind(this),\n onConnectionClosed: this._onConnectionClosed.bind(this),\n onConnectionAuthScopeChanged: this._onConnectionAuthScopeChanged.bind(this),\n getContainingSpaceForDocument: this._params.getContainingSpaceForDocument,\n });\n }\n\n @synchronized\n async removeReplicator(replicator: EchoReplicator) {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n invariant(this._replicators.has(replicator));\n await replicator.disconnect();\n this._replicators.delete(replicator);\n }\n\n async shouldAdvertize(peerId: PeerId, params: ShouldAdvertizeParams): Promise<boolean> {\n const connection = this._connections.get(peerId);\n if (!connection) {\n return false;\n }\n\n return connection.connection.shouldAdvertize(params);\n }\n\n private _onConnectionOpen(connection: ReplicatorConnection) {\n log('Connection opened', { peerId: connection.peerId });\n invariant(!this._connections.has(connection.peerId as PeerId));\n const reader = connection.readable.getReader();\n const writer = connection.writable.getWriter();\n const connectionEntry: ConnectionEntry = { connection, reader, writer, isOpen: true };\n this._connections.set(connection.peerId as PeerId, connectionEntry);\n\n queueMicrotask(async () => {\n try {\n while (true) {\n // TODO(dmaretskyi): Find a way to enforce backpressure on AM-repo.\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n this.emit('message', value);\n }\n } catch (err) {\n if (connectionEntry.isOpen) {\n log.catch(err);\n }\n }\n });\n\n log('emit peer-candidate', { peerId: connection.peerId });\n this._emitPeerCandidate(connection);\n }\n\n /**\n * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.\n * TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo\n */\n private _onConnectionAuthScopeChanged(connection: ReplicatorConnection) {\n log('Connection auth scope changed', { peerId: connection.peerId });\n const entry = this._connections.get(connection.peerId as PeerId);\n invariant(entry);\n this.emit('peer-disconnected', { peerId: connection.peerId as PeerId });\n this._emitPeerCandidate(connection);\n }\n\n private _onConnectionClosed(connection: ReplicatorConnection) {\n log('Connection closed', { peerId: connection.peerId });\n const entry = this._connections.get(connection.peerId as PeerId);\n invariant(entry);\n\n entry.isOpen = false;\n this.emit('peer-disconnected', { peerId: connection.peerId as PeerId });\n\n void entry.reader.cancel().catch((err) => log.catch(err));\n void entry.writer.abort().catch((err) => log.catch(err));\n\n this._connections.delete(connection.peerId as PeerId);\n }\n\n private _emitPeerCandidate(connection: ReplicatorConnection) {\n this.emit('peer-candidate', {\n peerId: connection.peerId as PeerId,\n peerMetadata: {\n // TODO(dmaretskyi): Refactor this.\n dxos_peerSource: 'EchoNetworkAdapter',\n } as any,\n });\n }\n}\n\ntype ConnectionEntry = {\n connection: ReplicatorConnection;\n reader: ReadableStreamDefaultReader<Message>;\n writer: WritableStreamDefaultWriter<Message>;\n isOpen: boolean;\n};\n", "//\n// Copyright 2024 DXOS.org\n// s\n\nimport { type MixedEncoding } from 'level-transcoder';\n\nimport { type StorageAdapterInterface, type Chunk, type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { LifecycleState, Resource } from '@dxos/context';\nimport { type BatchLevel, type SublevelDB } from '@dxos/kv-store';\nimport { type MaybePromise } from '@dxos/util';\n\nexport type LevelDBStorageAdapterParams = {\n db: SublevelDB;\n callbacks?: StorageCallbacks;\n};\n\nexport type BeforeSaveParams = { path: StorageKey; batch: BatchLevel };\n\nexport interface StorageCallbacks {\n beforeSave(params: BeforeSaveParams): MaybePromise<void>;\n afterSave(path: StorageKey): MaybePromise<void>;\n}\n\nexport class LevelDBStorageAdapter extends Resource implements StorageAdapterInterface {\n constructor(private readonly _params: LevelDBStorageAdapterParams) {\n super();\n }\n\n async load(keyArray: StorageKey): Promise<Uint8Array | undefined> {\n try {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n // TODO(mykola): this should be an error.\n return undefined;\n }\n return await this._params.db.get<StorageKey, Uint8Array>(keyArray, { ...encodingOptions });\n } catch (err: any) {\n if (isLevelDbNotFoundError(err)) {\n return undefined;\n }\n throw err;\n }\n }\n\n async save(keyArray: StorageKey, binary: Uint8Array): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n await this._params.callbacks?.beforeSave?.({ path: keyArray, batch });\n batch.put<StorageKey, Uint8Array>(keyArray, Buffer.from(binary), {\n ...encodingOptions,\n });\n await batch.write();\n\n await this._params.callbacks?.afterSave?.(keyArray);\n }\n\n async remove(keyArray: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n await this._params.db.del<StorageKey>(keyArray, { ...encodingOptions });\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return [];\n }\n const result: Chunk[] = [];\n for await (const [key, value] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n result.push({\n key,\n data: value,\n });\n }\n return result;\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n for await (const [key] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n batch.del<StorageKey>(key, { ...encodingOptions });\n }\n await batch.write();\n }\n}\n\nconst keyEncoder: MixedEncoding<StorageKey, Uint8Array, StorageKey> = {\n encode: (key: StorageKey): Uint8Array =>\n Buffer.from(key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-')),\n decode: (key: Uint8Array): StorageKey =>\n Buffer.from(key)\n .toString()\n .split('-')\n .map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%')),\n format: 'buffer',\n};\n\nexport const encodingOptions = {\n keyEncoding: keyEncoder,\n valueEncoding: 'buffer',\n};\n\nconst isLevelDbNotFoundError = (err: any): boolean => err.code === 'LEVEL_NOT_FOUND';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { type HostInfo, type SyncRepoRequest, type SyncRepoResponse } from '@dxos/protocols/proto/dxos/echo/service';\n\ntype ClientSyncState = {\n connected: boolean;\n send: (message: Message) => void;\n disconnect: () => void;\n};\n\n/**\n * Used to replicate with apps running on the same device.\n */\nexport class LocalHostNetworkAdapter extends NetworkAdapter {\n private readonly _peers: Map<PeerId, ClientSyncState> = new Map();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\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 this.emit('ready', {\n network: this,\n });\n }\n\n private readonly _connected = new Trigger();\n private _isConnected: boolean = false;\n\n /**\n * Called by `Repo` to connect to the network.\n *\n * @param peerId Our peer Id.\n */\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._isConnected = true;\n this._connected.wake();\n // No-op. Client always connects first\n }\n\n override send(message: Message): void {\n const peer = this._peers.get(message.targetId);\n invariant(peer, 'Peer not found.');\n peer.send(message);\n }\n\n async close() {\n this._peers.forEach((peer) => peer.disconnect());\n this.emit('close');\n }\n\n override disconnect(): void {\n // TODO(mykola): `disconnect` is not used anywhere in `Repo` from `@automerge/automerge-repo`. Should we remove it?\n // No-op\n }\n\n async whenConnected(): Promise<void> {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n syncRepo({ id, syncMessage }: SyncRepoRequest): Stream<SyncRepoResponse> {\n const peerId = this._getPeerId(id);\n\n return new Stream(({ next, close }) => {\n invariant(!this._peers.has(peerId), 'Peer already connected.');\n this._peers.set(peerId, {\n connected: true,\n send: (message) => {\n next({\n syncMessage: cbor.encode(message),\n });\n },\n disconnect: () => {\n this._peers.delete(peerId);\n close();\n this.emit('peer-disconnected', {\n peerId,\n });\n },\n });\n\n invariant(this._isConnected);\n this.emit('peer-candidate', {\n peerMetadata: {},\n peerId,\n });\n });\n }\n\n async sendSyncMessage({ id, syncMessage }: SyncRepoRequest): Promise<void> {\n invariant(this._isConnected);\n const message = cbor.decode(syncMessage!) as Message;\n this.emit('message', message);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n invariant(this._isConnected);\n invariant(this.peerId, 'Peer id not set.');\n return {\n peerId: this.peerId,\n };\n }\n\n private _getPeerId(id: string): PeerId {\n return id as PeerId;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type DocHandle, type AutomergeUrl, type DocumentId, type Repo } from '@dxos/automerge/automerge-repo';\nimport { cancelWithContext, type Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { type SpaceState, type SpaceDoc, SpaceDocVersion } from '@dxos/echo-protocol';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\ntype SpaceDocumentLinks = SpaceDoc['links'];\n\nexport interface AutomergeDocumentLoader {\n onObjectDocumentLoaded: Event<ObjectDocumentLoaded>;\n\n getAllHandles(): DocHandle<SpaceDoc>[];\n\n loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void>;\n loadObjectDocument(objectId: string | string[]): void;\n getSpaceRootDocHandle(): DocHandle<SpaceDoc>;\n createDocumentForObject(objectId: string): DocHandle<SpaceDoc>;\n onObjectLinksUpdated(links: SpaceDocumentLinks): void;\n onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string): void;\n\n /**\n * @returns objectIds for which we had document handles or were loading one.\n */\n clearHandleReferences(): string[];\n}\n\n/**\n * Manages object <-> docHandle binding and automerge document loading.\n */\n@trace.resource()\nexport class AutomergeDocumentLoaderImpl implements AutomergeDocumentLoader {\n private _spaceRootDocHandle: DocHandle<SpaceDoc> | null = null;\n /**\n * An object id pointer to a handle of the document where the object is stored inline.\n */\n private readonly _objectDocumentHandles = new Map<string, DocHandle<SpaceDoc>>();\n /**\n * If object was requested via loadObjectDocument but root document links weren't updated yet\n * loading will be triggered in onObjectLinksUpdated callback.\n */\n private readonly _objectsPendingDocumentLoad = new Set<string>();\n\n public readonly onObjectDocumentLoaded = new Event<ObjectDocumentLoaded>();\n\n constructor(\n private readonly _spaceId: SpaceId,\n private readonly _repo: Repo,\n /** Legacy Id */\n private readonly _spaceKey: PublicKey,\n ) {}\n\n getAllHandles(): DocHandle<SpaceDoc>[] {\n return this._spaceRootDocHandle != null\n ? [this._spaceRootDocHandle, ...new Set(this._objectDocumentHandles.values())]\n : [];\n }\n\n @trace.span({ showInBrowserTimeline: true })\n public async loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void> {\n if (this._spaceRootDocHandle != null) {\n return;\n }\n if (!spaceState.rootUrl) {\n log.error('Database opened with no rootUrl', { spaceId: this._spaceId });\n this._createContextBoundSpaceRootDocument(ctx);\n } else {\n const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);\n const doc = existingDocHandle.docSync();\n invariant(doc);\n if (doc.access == null) {\n this._initDocAccess(existingDocHandle);\n }\n this._spaceRootDocHandle = existingDocHandle;\n }\n }\n\n public loadObjectDocument(objectIdOrMany: string | string[]) {\n const objectIds = Array.isArray(objectIdOrMany) ? objectIdOrMany : [objectIdOrMany];\n let hasUrlsToLoad = false;\n const urlsToLoad: SpaceDoc['links'] = {};\n for (const objectId of objectIds) {\n invariant(this._spaceRootDocHandle);\n if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {\n continue;\n }\n const spaceRootDoc = this._spaceRootDocHandle.docSync();\n invariant(spaceRootDoc);\n const documentUrl = (spaceRootDoc.links ?? {})[objectId];\n if (documentUrl == null) {\n this._objectsPendingDocumentLoad.add(objectId);\n log.info('loading delayed until object links are initialized', { objectId });\n } else {\n urlsToLoad[objectId] = documentUrl;\n hasUrlsToLoad = true;\n }\n }\n if (hasUrlsToLoad) {\n this._loadLinkedObjects(urlsToLoad);\n }\n }\n\n public onObjectLinksUpdated(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n const linksAwaitingLoad = Object.entries(links).filter(([objectId]) =>\n this._objectsPendingDocumentLoad.has(objectId),\n );\n this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));\n linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));\n }\n\n public getSpaceRootDocHandle(): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n return this._spaceRootDocHandle;\n }\n\n public createDocumentForObject(objectId: string): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n const spaceDocHandle = this._repo.create<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n });\n this._initDocAccess(spaceDocHandle);\n this.onObjectBoundToDocument(spaceDocHandle, objectId);\n this._spaceRootDocHandle.change((newDoc: SpaceDoc) => {\n newDoc.links ??= {};\n newDoc.links[objectId] = spaceDocHandle.url;\n });\n return spaceDocHandle;\n }\n\n public onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string) {\n this._objectDocumentHandles.set(objectId, handle);\n }\n\n public clearHandleReferences(): string[] {\n const objectsWithHandles = [...this._objectDocumentHandles.keys()];\n this._objectDocumentHandles.clear();\n this._spaceRootDocHandle = null;\n return objectsWithHandles;\n }\n\n private _loadLinkedObjects(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n for (const [objectId, automergeUrl] of Object.entries(links)) {\n const logMeta = { objectId, automergeUrl };\n const objectDocumentHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {\n log.warn('object already inlined in a different document, ignoring the link', {\n ...logMeta,\n actualDocumentUrl: objectDocumentHandle.url,\n });\n continue;\n }\n if (objectDocumentHandle?.url === automergeUrl) {\n log.warn('object document was already loaded', logMeta);\n continue;\n }\n const handle = this._repo.find<SpaceDoc>(automergeUrl as DocumentId);\n log.debug('document loading triggered', logMeta);\n this._objectDocumentHandles.set(objectId, handle);\n void this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n\n private async _initDocHandle(ctx: Context, url: string) {\n const docHandle = this._repo.find<SpaceDoc>(url as DocumentId);\n while (true) {\n try {\n await warnAfterTimeout(5_000, 'Automerge root doc load timeout (CoreDatabase)', async () => {\n await cancelWithContext(ctx, docHandle.whenReady()); // TODO(dmaretskyi): Temporary 5s timeout for debugging.\n });\n break;\n } catch (err) {\n if (`${err}`.includes('Timeout')) {\n log.info('wraparound', { id: docHandle.documentId, state: docHandle.state });\n continue;\n }\n\n throw err;\n }\n }\n\n if (docHandle.state === 'unavailable') {\n throw new Error('Automerge document is unavailable');\n }\n\n return docHandle;\n }\n\n private _createContextBoundSpaceRootDocument(ctx: Context) {\n const docHandle = this._repo.create<SpaceDoc>();\n this._spaceRootDocHandle = docHandle;\n ctx.onDispose(() => {\n docHandle.delete();\n this._spaceRootDocHandle = null;\n });\n }\n\n private _initDocAccess(handle: DocHandle<SpaceDoc>) {\n handle.change((newDoc: SpaceDoc) => {\n newDoc.access ??= { spaceKey: this._spaceKey.toHex() };\n newDoc.access.spaceKey = this._spaceKey.toHex();\n });\n }\n\n private async _createObjectOnDocumentLoad(handle: DocHandle<SpaceDoc>, objectId: string) {\n try {\n await handle.doc(['ready']);\n const logMeta = { objectId, docUrl: handle.url };\n if (this.onObjectDocumentLoaded.listenerCount() === 0) {\n log.info('document loaded after all listeners were removed', logMeta);\n return;\n }\n const objectDocHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocHandle?.url !== handle.url) {\n log.warn('object was rebound while a document was loading, discarding handle', logMeta);\n return;\n }\n this.onObjectDocumentLoaded.emit({ handle, objectId });\n } catch (err) {\n const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;\n log.warn('failed to load a document', {\n objectId,\n automergeUrl: handle.url,\n retryLoading: shouldRetryLoading,\n err,\n });\n if (shouldRetryLoading) {\n await this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n }\n}\n\nexport interface ObjectDocumentLoaded {\n handle: DocHandle<SpaceDoc>;\n objectId: string;\n}\n\nexport interface DocumentChanges {\n createdObjectIds: string[];\n updatedObjectIds: string[];\n objectsToRebind: string[];\n linkedDocuments: {\n [echoId: string]: AutomergeUrl;\n };\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Message, cbor } from '@dxos/automerge/automerge-repo';\nimport { Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\nimport { ComplexMap, ComplexSet, defaultMap } from '@dxos/util';\n\nimport {\n type EchoReplicator,\n type EchoReplicatorContext,\n type ReplicatorConnection,\n type ShouldAdvertizeParams,\n} from './echo-replicator';\n\n// TODO(dmaretskyi): Move out of @dxos/echo-pipeline.\n\n/**\n * Used to replicate with other peers over the network.\n */\nexport class MeshEchoReplicator implements EchoReplicator {\n private readonly _connections = new Set<MeshReplicatorConnection>();\n /**\n * Using automerge peerId as a key.\n */\n private readonly _connectionsPerPeer = new Map<string, MeshReplicatorConnection>();\n\n /**\n * spaceKey -> deviceKey[]\n */\n private readonly _authorizedDevices = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n private _context: EchoReplicatorContext | null = null;\n\n async connect(context: EchoReplicatorContext): Promise<void> {\n this._context = context;\n }\n\n async disconnect() {\n for (const connection of this._connections) {\n await connection.close();\n }\n this._connections.clear();\n this._connectionsPerPeer.clear();\n\n this._context = null;\n }\n\n createExtension(): AutomergeReplicator {\n invariant(this._context);\n\n const connection: MeshReplicatorConnection = new MeshReplicatorConnection({\n ownPeerId: this._context.peerId,\n onRemoteConnected: async () => {\n log('onRemoteConnected', { peerId: connection.peerId });\n invariant(this._context);\n\n if (this._connectionsPerPeer.has(connection.peerId)) {\n this._context.onConnectionAuthScopeChanged(connection);\n } else {\n this._connectionsPerPeer.set(connection.peerId, connection);\n await connection.enable();\n this._context.onConnectionOpen(connection);\n }\n },\n onRemoteDisconnected: async () => {\n log('onRemoteDisconnected', { peerId: connection.peerId });\n this._context?.onConnectionClosed(connection);\n await connection.disable();\n this._connectionsPerPeer.delete(connection.peerId);\n this._connections.delete(connection);\n },\n shouldAdvertize: async (params: ShouldAdvertizeParams) => {\n log('shouldAdvertize', { peerId: connection.peerId, documentId: params.documentId });\n invariant(this._context);\n try {\n const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);\n if (!spaceKey) {\n log('space key not found for share policy check', {\n peerId: connection.peerId,\n documentId: params.documentId,\n });\n return false;\n }\n\n const authorizedDevices = this._authorizedDevices.get(spaceKey);\n\n if (!connection.remoteDeviceKey) {\n log('device key not found for share policy check', {\n peerId: connection.peerId,\n documentId: params.documentId,\n });\n return false;\n }\n\n const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;\n log('share policy check', {\n localPeer: this._context.peerId,\n remotePeer: connection.peerId,\n documentId: params.documentId,\n deviceKey: connection.remoteDeviceKey,\n spaceKey,\n isAuthorized,\n });\n return isAuthorized;\n } catch (err) {\n log.catch(err);\n return false;\n }\n },\n });\n this._connections.add(connection);\n\n return connection.replicatorExtension;\n }\n\n authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey) {\n log('authorizeDevice', { spaceKey, deviceKey });\n defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);\n }\n}\n\ntype MeshReplicatorConnectionParams = {\n ownPeerId: string;\n onRemoteConnected: () => Promise<void>;\n onRemoteDisconnected: () => Promise<void>;\n shouldAdvertize: (params: ShouldAdvertizeParams) => Promise<boolean>;\n};\n\nclass MeshReplicatorConnection extends Resource implements ReplicatorConnection {\n public readable: ReadableStream<Message>;\n public writable: WritableStream<Message>;\n public remoteDeviceKey: PublicKey | null = null;\n\n public readonly replicatorExtension: AutomergeReplicator;\n\n private _remotePeerId: string | null = null;\n private _isEnabled = false;\n\n constructor(private readonly _params: MeshReplicatorConnectionParams) {\n super();\n\n let readableStreamController!: ReadableStreamDefaultController<Message>;\n this.readable = new ReadableStream<Message>({\n start: (controller) => {\n readableStreamController = controller;\n this._ctx.onDispose(() => controller.close());\n },\n });\n\n this.writable = new WritableStream<Message>({\n write: async (message: Message, controller) => {\n // TODO(dmaretskyi): Show we block on RPC completing here?\n this.replicatorExtension.sendSyncMessage({ payload: cbor.encode(message) }).catch((err) => {\n controller.error(err);\n });\n },\n });\n\n this.replicatorExtension = new AutomergeReplicator(\n {\n peerId: this._params.ownPeerId,\n },\n {\n onStartReplication: async (info, remotePeerId /** Teleport ID */) => {\n // Note: We store only one extension per peer.\n // There can be a case where two connected peers have more than one teleport connection between them\n // and each of them uses different teleport connections to send messages.\n // It works because we receive messages from all teleport connections and Automerge Repo dedup them.\n // TODO(mykola): Use only one teleport connection per peer.\n\n // TODO(dmaretskyi): Critical bug.\n // - two peers get connected via swarm 1\n // - they get connected via swarm 2\n // - swarm 1 gets disconnected\n // - automerge repo thinks that peer 2 got disconnected even though swarm 2 is still active\n\n this.remoteDeviceKey = remotePeerId;\n\n // Set automerge id.\n this._remotePeerId = info.id;\n\n log('onStartReplication', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n\n await this._params.onRemoteConnected();\n },\n onSyncMessage: async ({ payload }) => {\n if (!this._isEnabled) {\n return;\n }\n const message = cbor.decode(payload) as Message;\n // Note: automerge Repo dedup messages.\n readableStreamController.enqueue(message);\n },\n onClose: async () => {\n if (!this._isEnabled) {\n return;\n }\n await this._params.onRemoteDisconnected();\n },\n },\n );\n }\n\n get peerId(): string {\n invariant(this._remotePeerId != null, 'Remote peer has not connected yet.');\n return this._remotePeerId;\n }\n\n async shouldAdvertize(params: ShouldAdvertizeParams): Promise<boolean> {\n return this._params.shouldAdvertize(params);\n }\n\n /**\n * Start exchanging messages with the remote peer.\n * Call after the remote peer has connected.\n */\n async enable() {\n invariant(this._remotePeerId != null, 'Remote peer has not connected yet.');\n this._isEnabled = true;\n }\n\n /**\n * Stop exchanging messages with the remote peer.\n */\n async disable() {\n this._isEnabled = false;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["Event", "next", "automerge", "getBackend", "getHeads", "Repo", "Context", "invariant", "PublicKey", "log", "objectPointerCodec", "trace", "mapValues", "Trigger", "synchronized", "NetworkAdapter", "LifecycleState", "invariant", "log", "EchoNetworkAdapter", "constructor", "_params", "_replicators", "Set", "_connections", "Map", "_lifecycleState", "CLOSED", "_connected", "connect", "peerId", "peerMetadata", "wake", "send", "message", "connectionEntry", "get", "targetId", "Error", "writer", "write", "catch", "err", "isOpen", "disconnect", "open", "OPEN", "emit", "network", "close", "replicator", "clear", "whenConnected", "wait", "timeout", "addReplicator", "has", "add", "onConnectionOpen", "_onConnectionOpen", "bind", "onConnectionClosed", "_onConnectionClosed", "onConnectionAuthScopeChanged", "_onConnectionAuthScopeChanged", "getContainingSpaceForDocument", "removeReplicator", "delete", "shouldAdvertize", "params", "connection", "reader", "readable", "getReader", "writable", "getWriter", "set", "queueMicrotask", "done", "value", "read", "_emitPeerCandidate", "entry", "cancel", "abort", "dxos_peerSource", "LifecycleState", "Resource", "LevelDBStorageAdapter", "Resource", "constructor", "_params", "load", "keyArray", "_lifecycleState", "LifecycleState", "OPEN", "undefined", "db", "get", "encodingOptions", "err", "isLevelDbNotFoundError", "save", "binary", "batch", "callbacks", "beforeSave", "path", "put", "Buffer", "from", "write", "afterSave", "remove", "del", "loadRange", "keyPrefix", "result", "key", "value", "iterator", "gte", "lte", "push", "data", "removeRange", "keyEncoder", "encode", "map", "k", "replaceAll", "join", "decode", "toString", "split", "format", "keyEncoding", "valueEncoding", "code", "Trigger", "NetworkAdapter", "cbor", "Stream", "invariant", "LocalHostNetworkAdapter", "_peers", "Map", "_connected", "_isConnected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "peer", "get", "targetId", "close", "forEach", "disconnect", "whenConnected", "wait", "timeout", "syncRepo", "id", "syncMessage", "_getPeerId", "next", "has", "set", "connected", "encode", "delete", "peerMetadata", "sendSyncMessage", "decode", "getHostInfo", "AutomergeHost", "constructor", "db", "indexMetadataStore", "_ctx", "Context", "_echoNetworkAdapter", "EchoNetworkAdapter", "getContainingSpaceForDocument", "_getContainingSpaceForDocument", "bind", "_requestedDocs", "Set", "_storage", "LevelDBStorageAdapter", "callbacks", "beforeSave", "params", "_beforeSave", "afterSave", "_afterSave", "_indexMetadataStore", "open", "_peerId", "PublicKey", "random", "toHex", "_clientNetwork", "LocalHostNetworkAdapter", "_repo", "Repo", "peerId", "sharePolicy", "_sharePolicy", "storage", "network", "ready", "whenConnected", "close", "dispose", "repo", "addReplicator", "replicator", "removeReplicator", "documentId", "startsWith", "doc", "handles", "docSync", "isRequested", "has", "log", "peerMetadata", "peerMetadataByPeerId", "dxos_peerSource", "shouldAdvertize", "path", "batch", "handle", "spaceKey", "getSpaceKeyFromDoc", "undefined", "lastAvailableHash", "getHeads", "objectIds", "Object", "keys", "objects", "encodedIds", "map", "objectId", "objectPointerCodec", "encode", "idToLastHash", "Map", "id", "markDirty", "notifyMarkedDirty", "_automergeDocs", "mapValues", "state", "hasDoc", "heads", "automerge", "data", "value", "key", "err", "_automergePeers", "peers", "spaceKeyHex", "from", "flush", "states", "Promise", "all", "invariant", "find", "waitForHeads", "syncRepo", "request", "sendSyncMessage", "getHostInfo", "trace", "info", "depth", "span", "showInBrowserTimeline", "resource", "rawSpaceKey", "access", "experimental_spaceKey", "String", "whenReady", "unavailableHeads", "Event", "wrap", "waitForCondition", "changeHash", "values", "changeIsPresentInDoc", "delete", "size", "getBackend", "getChangeByHash", "Event", "cancelWithContext", "warnAfterTimeout", "SpaceDocVersion", "invariant", "log", "trace", "AutomergeDocumentLoaderImpl", "constructor", "_spaceId", "_repo", "_spaceKey", "_spaceRootDocHandle", "_objectDocumentHandles", "Map", "_objectsPendingDocumentLoad", "Set", "onObjectDocumentLoaded", "getAllHandles", "values", "loadSpaceRootDocHandle", "ctx", "spaceState", "rootUrl", "error", "spaceId", "_createContextBoundSpaceRootDocument", "existingDocHandle", "_initDocHandle", "doc", "docSync", "access", "_initDocAccess", "loadObjectDocument", "objectIdOrMany", "objectIds", "Array", "isArray", "hasUrlsToLoad", "urlsToLoad", "objectId", "has", "spaceRootDoc", "documentUrl", "links", "add", "info", "_loadLinkedObjects", "onObjectLinksUpdated", "linksAwaitingLoad", "Object", "entries", "filter", "fromEntries", "forEach", "delete", "getSpaceRootDocHandle", "createDocumentForObject", "spaceDocHandle", "create", "version", "CURRENT", "onObjectBoundToDocument", "change", "newDoc", "url", "handle", "set", "clearHandleReferences", "objectsWithHandles", "keys", "clear", "automergeUrl", "logMeta", "objectDocumentHandle", "get", "warn", "actualDocumentUrl", "find", "debug", "_createObjectOnDocumentLoad", "docHandle", "whenReady", "err", "includes", "id", "documentId", "state", "Error", "onDispose", "spaceKey", "toHex", "docUrl", "listenerCount", "objectDocHandle", "emit", "shouldRetryLoading", "retryLoading", "span", "showInBrowserTimeline", "resource", "cbor", "Resource", "invariant", "PublicKey", "log", "AutomergeReplicator", "ComplexMap", "ComplexSet", "defaultMap", "MeshEchoReplicator", "_connections", "Set", "_connectionsPerPeer", "Map", "_authorizedDevices", "hash", "_context", "connect", "context", "disconnect", "connection", "close", "clear", "createExtension", "MeshReplicatorConnection", "ownPeerId", "peerId", "onRemoteConnected", "has", "onConnectionAuthScopeChanged", "set", "enable", "onConnectionOpen", "onRemoteDisconnected", "onConnectionClosed", "disable", "delete", "shouldAdvertize", "params", "documentId", "spaceKey", "getContainingSpaceForDocument", "authorizedDevices", "get", "remoteDeviceKey", "isAuthorized", "localPeer", "remotePeer", "deviceKey", "err", "catch", "add", "replicatorExtension", "authorizeDevice", "constructor", "_params", "_remotePeerId", "_isEnabled", "readableStreamController", "readable", "ReadableStream", "start", "controller", "_ctx", "onDispose", "writable", "WritableStream", "write", "message", "sendSyncMessage", "payload", "encode", "error", "onStartReplication", "info", "remotePeerId", "id", "thisPeerId", "toHex", "onSyncMessage", "decode", "enqueue", "onClose"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { next as automerge, getBackend, getHeads, type Doc, type Heads } from '@dxos/automerge/automerge';\nimport {\n Repo,\n type DocHandle,\n type DocHandleChangePayload,\n type DocumentId,\n type PeerId,\n type StorageAdapterInterface,\n} from '@dxos/automerge/automerge-repo';\nimport { type Stream } from '@dxos/codec-protobuf';\nimport { Context, type Lifecycle } from '@dxos/context';\nimport { type SpaceDoc } from '@dxos/echo-protocol';\nimport { type IndexMetadataStore } from '@dxos/indexing';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { type SublevelDB } from '@dxos/kv-store';\nimport { objectPointerCodec } from '@dxos/protocols';\nimport {\n type FlushRequest,\n type HostInfo,\n type SyncRepoRequest,\n type SyncRepoResponse,\n} from '@dxos/protocols/proto/dxos/echo/service';\nimport { trace } from '@dxos/tracing';\nimport { mapValues } from '@dxos/util';\n\nimport { EchoNetworkAdapter } from './echo-network-adapter';\nimport { type EchoReplicator } from './echo-replicator';\nimport { LevelDBStorageAdapter, type BeforeSaveParams } from './leveldb-storage-adapter';\nimport { LocalHostNetworkAdapter } from './local-host-network-adapter';\n\n// TODO: Remove\nexport type { DocumentId };\n\nexport type AutomergeHostParams = {\n db: SublevelDB;\n\n indexMetadataStore: IndexMetadataStore;\n};\n\n@trace.resource()\nexport class AutomergeHost {\n private readonly _indexMetadataStore: IndexMetadataStore;\n private readonly _ctx = new Context();\n private readonly _echoNetworkAdapter = new EchoNetworkAdapter({\n getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),\n });\n\n private _repo!: Repo;\n private _clientNetwork!: LocalHostNetworkAdapter;\n private _storage!: StorageAdapterInterface & Lifecycle;\n\n @trace.info()\n private _peerId!: string;\n\n constructor({ db, indexMetadataStore }: AutomergeHostParams) {\n this._storage = new LevelDBStorageAdapter({\n db,\n callbacks: {\n beforeSave: async (params) => this._beforeSave(params),\n afterSave: async () => this._afterSave(),\n },\n });\n this._indexMetadataStore = indexMetadataStore;\n }\n\n async open() {\n // TODO(burdon): Should this be stable?\n this._peerId = `host-${PublicKey.random().toHex()}` as PeerId;\n\n await this._storage.open?.();\n this._clientNetwork = new LocalHostNetworkAdapter();\n\n // Construct the automerge repo.\n this._repo = new Repo({\n peerId: this._peerId as PeerId,\n sharePolicy: this._sharePolicy.bind(this),\n storage: this._storage,\n network: [\n // Downstream client.\n this._clientNetwork,\n // Upstream swarm.\n this._echoNetworkAdapter,\n ],\n });\n\n this._clientNetwork.ready();\n await this._echoNetworkAdapter.open();\n await this._clientNetwork.whenConnected();\n await this._echoNetworkAdapter.whenConnected();\n }\n\n async close() {\n await this._storage.close?.();\n await this._clientNetwork.close();\n await this._echoNetworkAdapter.close();\n await this._ctx.dispose();\n }\n\n get repo(): Repo {\n return this._repo;\n }\n\n async addReplicator(replicator: EchoReplicator) {\n await this._echoNetworkAdapter.addReplicator(replicator);\n }\n\n async removeReplicator(replicator: EchoReplicator) {\n await this._echoNetworkAdapter.removeReplicator(replicator);\n }\n\n // TODO(dmaretskyi): Share based on HALO permissions and space affinity.\n // Hosts, running in the worker, don't share documents unless requested by other peers.\n // NOTE: If both peers return sharePolicy=false the replication will not happen\n // https://github.com/automerge/automerge-repo/pull/292\n private async _sharePolicy(\n peerId: PeerId /* device key */,\n documentId?: DocumentId /* space key */,\n ): Promise<boolean> {\n if (peerId.startsWith('client-')) {\n return false; // Only send docs to clients if they are requested.\n }\n\n if (!documentId) {\n return false;\n }\n\n const peerMetadata = this.repo.peerMetadataByPeerId[peerId];\n if ((peerMetadata as any)?.dxos_peerSource === 'EchoNetworkAdapter') {\n return this._echoNetworkAdapter.shouldAdvertize(peerId, { documentId });\n }\n\n return false;\n }\n\n private async _beforeSave({ path, batch }: BeforeSaveParams) {\n const handle = this._repo.handles[path[0] as DocumentId];\n if (!handle) {\n return;\n }\n const doc = handle.docSync();\n if (!doc) {\n return;\n }\n\n const spaceKey = getSpaceKeyFromDoc(doc) ?? undefined;\n\n const lastAvailableHash = getHeads(doc);\n\n const objectIds = Object.keys(doc.objects ?? {});\n const encodedIds = objectIds.map((objectId) =>\n objectPointerCodec.encode({ documentId: handle.documentId, objectId, spaceKey }),\n );\n const idToLastHash = new Map(encodedIds.map((id) => [id, lastAvailableHash]));\n this._indexMetadataStore.markDirty(idToLastHash, batch);\n }\n\n /**\n * Called by AutomergeStorageAdapter after levelDB batch commit.\n */\n private async _afterSave() {\n this._indexMetadataStore.notifyMarkedDirty();\n }\n\n @trace.info({ depth: null })\n private _automergeDocs() {\n return mapValues(this._repo.handles, (handle) => ({\n state: handle.state,\n hasDoc: !!handle.docSync(),\n heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,\n data:\n handle.docSync() &&\n mapValues(handle.docSync(), (value, key) => {\n try {\n switch (key) {\n case 'access':\n case 'links':\n return value;\n case 'objects':\n return Object.keys(value as any);\n default:\n return `${value}`;\n }\n } catch (err) {\n return `${err}`;\n }\n }),\n }));\n }\n\n @trace.info({ depth: null })\n private _automergePeers() {\n return this._repo.peers;\n }\n\n private async _getContainingSpaceForDocument(documentId: string): Promise<PublicKey | null> {\n const doc = this._repo.handles[documentId as any]?.docSync();\n if (!doc) {\n return null;\n }\n\n const spaceKeyHex = getSpaceKeyFromDoc(doc);\n if (!spaceKeyHex) {\n return null;\n }\n\n return PublicKey.from(spaceKeyHex);\n }\n\n //\n // Methods for client-services.\n //\n @trace.span({ showInBrowserTimeline: true })\n async flush({ states }: FlushRequest): Promise<void> {\n // Note: Wait for all requested documents to be loaded/synced from thin-client.\n await Promise.all(\n states?.map(async ({ heads, documentId }) => {\n invariant(heads, 'heads are required for flush');\n const handle = this.repo.handles[documentId as DocumentId] ?? this._repo.find(documentId as DocumentId);\n await waitForHeads(handle, heads);\n }) ?? [],\n );\n\n await this._repo.flush(states?.map(({ documentId }) => documentId as DocumentId));\n }\n\n syncRepo(request: SyncRepoRequest): Stream<SyncRepoResponse> {\n return this._clientNetwork.syncRepo(request);\n }\n\n sendSyncMessage(request: SyncRepoRequest): Promise<void> {\n return this._clientNetwork.sendSyncMessage(request);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n return this._clientNetwork.getHostInfo();\n }\n}\n\nexport const getSpaceKeyFromDoc = (doc: any): string | null => {\n // experimental_spaceKey is set on old documents, new ones are created with doc.access.spaceKey\n const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;\n if (rawSpaceKey == null) {\n return null;\n }\n\n return String(rawSpaceKey);\n};\n\nconst waitForHeads = async (handle: DocHandle<SpaceDoc>, heads: Heads) => {\n await handle.whenReady();\n const unavailableHeads = new Set(heads);\n\n await Event.wrap<DocHandleChangePayload<SpaceDoc>>(handle, 'change').waitForCondition(() => {\n // Check if unavailable heads became available.\n for (const changeHash of unavailableHeads.values()) {\n if (changeIsPresentInDoc(handle.docSync(), changeHash)) {\n unavailableHeads.delete(changeHash);\n }\n }\n\n if (unavailableHeads.size === 0) {\n return true;\n }\n return false;\n });\n};\n\nconst changeIsPresentInDoc = (doc: Doc<any>, changeHash: string): boolean => {\n return !!getBackend(doc).getChangeByHash(changeHash);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger, synchronized } from '@dxos/async';\nimport { type Message, NetworkAdapter, type PeerId, type PeerMetadata } from '@dxos/automerge/automerge-repo';\nimport { LifecycleState } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type EchoReplicator, type ReplicatorConnection, type ShouldAdvertizeParams } from './echo-replicator';\n\nexport type EchoNetworkAdapterParams = {\n getContainingSpaceForDocument: (documentId: string) => Promise<PublicKey | null>;\n};\n\n/**\n * Manages a set of {@link EchoReplicator} instances.\n */\nexport class EchoNetworkAdapter extends NetworkAdapter {\n private readonly _replicators = new Set<EchoReplicator>();\n /**\n * Remote peer id -> connection.\n */\n private readonly _connections = new Map<PeerId, ConnectionEntry>();\n private _lifecycleState: LifecycleState = LifecycleState.CLOSED;\n private readonly _connected = new Trigger();\n\n constructor(private readonly _params: EchoNetworkAdapterParams) {\n super();\n }\n\n override connect(peerId: PeerId, peerMetadata?: PeerMetadata | undefined): void {\n this.peerId = peerId;\n this.peerMetadata = peerMetadata;\n this._connected.wake();\n }\n\n override send(message: Message): void {\n const connectionEntry = this._connections.get(message.targetId);\n if (!connectionEntry) {\n throw new Error('Connection not found.');\n }\n\n // TODO(dmaretskyi): Find a way to enforce backpressure on AM-repo.\n connectionEntry.writer.write(message).catch((err) => {\n if (connectionEntry.isOpen) {\n log.catch(err);\n }\n });\n }\n\n override disconnect(): void {\n // No-op\n }\n\n @synchronized\n async open() {\n invariant(this._lifecycleState === LifecycleState.CLOSED);\n this._lifecycleState = LifecycleState.OPEN;\n\n log('emit ready');\n this.emit('ready', {\n network: this,\n });\n }\n\n @synchronized\n async close() {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n\n for (const replicator of this._replicators) {\n await replicator.disconnect();\n }\n this._replicators.clear();\n\n this._lifecycleState = LifecycleState.CLOSED;\n }\n\n async whenConnected() {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n @synchronized\n async addReplicator(replicator: EchoReplicator) {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n invariant(this.peerId);\n invariant(!this._replicators.has(replicator));\n\n this._replicators.add(replicator);\n await replicator.connect({\n peerId: this.peerId,\n onConnectionOpen: this._onConnectionOpen.bind(this),\n onConnectionClosed: this._onConnectionClosed.bind(this),\n onConnectionAuthScopeChanged: this._onConnectionAuthScopeChanged.bind(this),\n getContainingSpaceForDocument: this._params.getContainingSpaceForDocument,\n });\n }\n\n @synchronized\n async removeReplicator(replicator: EchoReplicator) {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n invariant(this._replicators.has(replicator));\n await replicator.disconnect();\n this._replicators.delete(replicator);\n }\n\n async shouldAdvertize(peerId: PeerId, params: ShouldAdvertizeParams): Promise<boolean> {\n const connection = this._connections.get(peerId);\n if (!connection) {\n return false;\n }\n\n return connection.connection.shouldAdvertize(params);\n }\n\n private _onConnectionOpen(connection: ReplicatorConnection) {\n log('Connection opened', { peerId: connection.peerId });\n invariant(!this._connections.has(connection.peerId as PeerId));\n const reader = connection.readable.getReader();\n const writer = connection.writable.getWriter();\n const connectionEntry: ConnectionEntry = { connection, reader, writer, isOpen: true };\n this._connections.set(connection.peerId as PeerId, connectionEntry);\n\n queueMicrotask(async () => {\n try {\n while (true) {\n // TODO(dmaretskyi): Find a way to enforce backpressure on AM-repo.\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n this.emit('message', value);\n }\n } catch (err) {\n if (connectionEntry.isOpen) {\n log.catch(err);\n }\n }\n });\n\n log('emit peer-candidate', { peerId: connection.peerId });\n this._emitPeerCandidate(connection);\n }\n\n /**\n * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.\n * TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo\n */\n private _onConnectionAuthScopeChanged(connection: ReplicatorConnection) {\n log('Connection auth scope changed', { peerId: connection.peerId });\n const entry = this._connections.get(connection.peerId as PeerId);\n invariant(entry);\n this.emit('peer-disconnected', { peerId: connection.peerId as PeerId });\n this._emitPeerCandidate(connection);\n }\n\n private _onConnectionClosed(connection: ReplicatorConnection) {\n log('Connection closed', { peerId: connection.peerId });\n const entry = this._connections.get(connection.peerId as PeerId);\n invariant(entry);\n\n entry.isOpen = false;\n this.emit('peer-disconnected', { peerId: connection.peerId as PeerId });\n\n void entry.reader.cancel().catch((err) => log.catch(err));\n void entry.writer.abort().catch((err) => log.catch(err));\n\n this._connections.delete(connection.peerId as PeerId);\n }\n\n private _emitPeerCandidate(connection: ReplicatorConnection) {\n this.emit('peer-candidate', {\n peerId: connection.peerId as PeerId,\n peerMetadata: {\n // TODO(dmaretskyi): Refactor this.\n dxos_peerSource: 'EchoNetworkAdapter',\n } as any,\n });\n }\n}\n\ntype ConnectionEntry = {\n connection: ReplicatorConnection;\n reader: ReadableStreamDefaultReader<Message>;\n writer: WritableStreamDefaultWriter<Message>;\n isOpen: boolean;\n};\n", "//\n// Copyright 2024 DXOS.org\n// s\n\nimport { type MixedEncoding } from 'level-transcoder';\n\nimport { type StorageAdapterInterface, type Chunk, type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { LifecycleState, Resource } from '@dxos/context';\nimport { type BatchLevel, type SublevelDB } from '@dxos/kv-store';\nimport { type MaybePromise } from '@dxos/util';\n\nexport type LevelDBStorageAdapterParams = {\n db: SublevelDB;\n callbacks?: StorageCallbacks;\n};\n\nexport type BeforeSaveParams = { path: StorageKey; batch: BatchLevel };\n\nexport interface StorageCallbacks {\n beforeSave(params: BeforeSaveParams): MaybePromise<void>;\n afterSave(path: StorageKey): MaybePromise<void>;\n}\n\nexport class LevelDBStorageAdapter extends Resource implements StorageAdapterInterface {\n constructor(private readonly _params: LevelDBStorageAdapterParams) {\n super();\n }\n\n async load(keyArray: StorageKey): Promise<Uint8Array | undefined> {\n try {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n // TODO(mykola): this should be an error.\n return undefined;\n }\n return await this._params.db.get<StorageKey, Uint8Array>(keyArray, { ...encodingOptions });\n } catch (err: any) {\n if (isLevelDbNotFoundError(err)) {\n return undefined;\n }\n throw err;\n }\n }\n\n async save(keyArray: StorageKey, binary: Uint8Array): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n await this._params.callbacks?.beforeSave?.({ path: keyArray, batch });\n batch.put<StorageKey, Uint8Array>(keyArray, Buffer.from(binary), {\n ...encodingOptions,\n });\n await batch.write();\n\n await this._params.callbacks?.afterSave?.(keyArray);\n }\n\n async remove(keyArray: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n await this._params.db.del<StorageKey>(keyArray, { ...encodingOptions });\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return [];\n }\n const result: Chunk[] = [];\n for await (const [key, value] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n result.push({\n key,\n data: value,\n });\n }\n return result;\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n for await (const [key] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n batch.del<StorageKey>(key, { ...encodingOptions });\n }\n await batch.write();\n }\n}\n\nconst keyEncoder: MixedEncoding<StorageKey, Uint8Array, StorageKey> = {\n encode: (key: StorageKey): Uint8Array =>\n Buffer.from(key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-')),\n decode: (key: Uint8Array): StorageKey =>\n Buffer.from(key)\n .toString()\n .split('-')\n .map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%')),\n format: 'buffer',\n};\n\nexport const encodingOptions = {\n keyEncoding: keyEncoder,\n valueEncoding: 'buffer',\n};\n\nconst isLevelDbNotFoundError = (err: any): boolean => err.code === 'LEVEL_NOT_FOUND';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { type HostInfo, type SyncRepoRequest, type SyncRepoResponse } from '@dxos/protocols/proto/dxos/echo/service';\n\ntype ClientSyncState = {\n connected: boolean;\n send: (message: Message) => void;\n disconnect: () => void;\n};\n\n/**\n * Used to replicate with apps running on the same device.\n */\nexport class LocalHostNetworkAdapter extends NetworkAdapter {\n private readonly _peers: Map<PeerId, ClientSyncState> = new Map();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\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 this.emit('ready', {\n network: this,\n });\n }\n\n private readonly _connected = new Trigger();\n private _isConnected: boolean = false;\n\n /**\n * Called by `Repo` to connect to the network.\n *\n * @param peerId Our peer Id.\n */\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._isConnected = true;\n this._connected.wake();\n // No-op. Client always connects first\n }\n\n override send(message: Message): void {\n const peer = this._peers.get(message.targetId);\n invariant(peer, 'Peer not found.');\n peer.send(message);\n }\n\n async close() {\n this._peers.forEach((peer) => peer.disconnect());\n this.emit('close');\n }\n\n override disconnect(): void {\n // TODO(mykola): `disconnect` is not used anywhere in `Repo` from `@automerge/automerge-repo`. Should we remove it?\n // No-op\n }\n\n async whenConnected(): Promise<void> {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n syncRepo({ id, syncMessage }: SyncRepoRequest): Stream<SyncRepoResponse> {\n const peerId = this._getPeerId(id);\n\n return new Stream(({ next, close }) => {\n invariant(!this._peers.has(peerId), 'Peer already connected.');\n this._peers.set(peerId, {\n connected: true,\n send: (message) => {\n next({\n syncMessage: cbor.encode(message),\n });\n },\n disconnect: () => {\n this._peers.delete(peerId);\n close();\n this.emit('peer-disconnected', {\n peerId,\n });\n },\n });\n\n invariant(this._isConnected);\n this.emit('peer-candidate', {\n peerMetadata: {},\n peerId,\n });\n });\n }\n\n async sendSyncMessage({ id, syncMessage }: SyncRepoRequest): Promise<void> {\n invariant(this._isConnected);\n const message = cbor.decode(syncMessage!) as Message;\n this.emit('message', message);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n invariant(this._isConnected);\n invariant(this.peerId, 'Peer id not set.');\n return {\n peerId: this.peerId,\n };\n }\n\n private _getPeerId(id: string): PeerId {\n return id as PeerId;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type DocHandle, type AutomergeUrl, type DocumentId, type Repo } from '@dxos/automerge/automerge-repo';\nimport { cancelWithContext, type Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { type SpaceState, type SpaceDoc, SpaceDocVersion } from '@dxos/echo-protocol';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\ntype SpaceDocumentLinks = SpaceDoc['links'];\n\nexport interface AutomergeDocumentLoader {\n onObjectDocumentLoaded: Event<ObjectDocumentLoaded>;\n\n getAllHandles(): DocHandle<SpaceDoc>[];\n\n loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void>;\n loadObjectDocument(objectId: string | string[]): void;\n getSpaceRootDocHandle(): DocHandle<SpaceDoc>;\n createDocumentForObject(objectId: string): DocHandle<SpaceDoc>;\n onObjectLinksUpdated(links: SpaceDocumentLinks): void;\n onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string): void;\n\n /**\n * @returns objectIds for which we had document handles or were loading one.\n */\n clearHandleReferences(): string[];\n}\n\n/**\n * Manages object <-> docHandle binding and automerge document loading.\n */\n@trace.resource()\nexport class AutomergeDocumentLoaderImpl implements AutomergeDocumentLoader {\n private _spaceRootDocHandle: DocHandle<SpaceDoc> | null = null;\n /**\n * An object id pointer to a handle of the document where the object is stored inline.\n */\n private readonly _objectDocumentHandles = new Map<string, DocHandle<SpaceDoc>>();\n /**\n * If object was requested via loadObjectDocument but root document links weren't updated yet\n * loading will be triggered in onObjectLinksUpdated callback.\n */\n private readonly _objectsPendingDocumentLoad = new Set<string>();\n\n public readonly onObjectDocumentLoaded = new Event<ObjectDocumentLoaded>();\n\n constructor(\n private readonly _spaceId: SpaceId,\n private readonly _repo: Repo,\n /** Legacy Id */\n private readonly _spaceKey: PublicKey,\n ) {}\n\n getAllHandles(): DocHandle<SpaceDoc>[] {\n return this._spaceRootDocHandle != null\n ? [this._spaceRootDocHandle, ...new Set(this._objectDocumentHandles.values())]\n : [];\n }\n\n @trace.span({ showInBrowserTimeline: true })\n public async loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void> {\n if (this._spaceRootDocHandle != null) {\n return;\n }\n if (!spaceState.rootUrl) {\n log.error('Database opened with no rootUrl', { spaceId: this._spaceId });\n this._createContextBoundSpaceRootDocument(ctx);\n } else {\n const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);\n const doc = existingDocHandle.docSync();\n invariant(doc);\n if (doc.access == null) {\n this._initDocAccess(existingDocHandle);\n }\n this._spaceRootDocHandle = existingDocHandle;\n }\n }\n\n public loadObjectDocument(objectIdOrMany: string | string[]) {\n const objectIds = Array.isArray(objectIdOrMany) ? objectIdOrMany : [objectIdOrMany];\n let hasUrlsToLoad = false;\n const urlsToLoad: SpaceDoc['links'] = {};\n for (const objectId of objectIds) {\n invariant(this._spaceRootDocHandle);\n if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {\n continue;\n }\n const spaceRootDoc = this._spaceRootDocHandle.docSync();\n invariant(spaceRootDoc);\n const documentUrl = (spaceRootDoc.links ?? {})[objectId];\n if (documentUrl == null) {\n this._objectsPendingDocumentLoad.add(objectId);\n log.info('loading delayed until object links are initialized', { objectId });\n } else {\n urlsToLoad[objectId] = documentUrl;\n hasUrlsToLoad = true;\n }\n }\n if (hasUrlsToLoad) {\n this._loadLinkedObjects(urlsToLoad);\n }\n }\n\n public onObjectLinksUpdated(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n const linksAwaitingLoad = Object.entries(links).filter(([objectId]) =>\n this._objectsPendingDocumentLoad.has(objectId),\n );\n this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));\n linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));\n }\n\n public getSpaceRootDocHandle(): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n return this._spaceRootDocHandle;\n }\n\n public createDocumentForObject(objectId: string): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n const spaceDocHandle = this._repo.create<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n });\n this._initDocAccess(spaceDocHandle);\n this.onObjectBoundToDocument(spaceDocHandle, objectId);\n this._spaceRootDocHandle.change((newDoc: SpaceDoc) => {\n newDoc.links ??= {};\n newDoc.links[objectId] = spaceDocHandle.url;\n });\n return spaceDocHandle;\n }\n\n public onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string) {\n this._objectDocumentHandles.set(objectId, handle);\n }\n\n public clearHandleReferences(): string[] {\n const objectsWithHandles = [...this._objectDocumentHandles.keys()];\n this._objectDocumentHandles.clear();\n this._spaceRootDocHandle = null;\n return objectsWithHandles;\n }\n\n private _loadLinkedObjects(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n for (const [objectId, automergeUrl] of Object.entries(links)) {\n const logMeta = { objectId, automergeUrl };\n const objectDocumentHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {\n log.warn('object already inlined in a different document, ignoring the link', {\n ...logMeta,\n actualDocumentUrl: objectDocumentHandle.url,\n });\n continue;\n }\n if (objectDocumentHandle?.url === automergeUrl) {\n log.warn('object document was already loaded', logMeta);\n continue;\n }\n const handle = this._repo.find<SpaceDoc>(automergeUrl as DocumentId);\n log.debug('document loading triggered', logMeta);\n this._objectDocumentHandles.set(objectId, handle);\n void this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n\n private async _initDocHandle(ctx: Context, url: string) {\n const docHandle = this._repo.find<SpaceDoc>(url as DocumentId);\n while (true) {\n try {\n await warnAfterTimeout(5_000, 'Automerge root doc load timeout (CoreDatabase)', async () => {\n await cancelWithContext(ctx, docHandle.whenReady()); // TODO(dmaretskyi): Temporary 5s timeout for debugging.\n });\n break;\n } catch (err) {\n if (`${err}`.includes('Timeout')) {\n log.info('wraparound', { id: docHandle.documentId, state: docHandle.state });\n continue;\n }\n\n throw err;\n }\n }\n\n if (docHandle.state === 'unavailable') {\n throw new Error('Automerge document is unavailable');\n }\n\n return docHandle;\n }\n\n private _createContextBoundSpaceRootDocument(ctx: Context) {\n const docHandle = this._repo.create<SpaceDoc>();\n this._spaceRootDocHandle = docHandle;\n ctx.onDispose(() => {\n docHandle.delete();\n this._spaceRootDocHandle = null;\n });\n }\n\n private _initDocAccess(handle: DocHandle<SpaceDoc>) {\n handle.change((newDoc: SpaceDoc) => {\n newDoc.access ??= { spaceKey: this._spaceKey.toHex() };\n newDoc.access.spaceKey = this._spaceKey.toHex();\n });\n }\n\n private async _createObjectOnDocumentLoad(handle: DocHandle<SpaceDoc>, objectId: string) {\n try {\n await handle.doc(['ready']);\n const logMeta = { objectId, docUrl: handle.url };\n if (this.onObjectDocumentLoaded.listenerCount() === 0) {\n log.info('document loaded after all listeners were removed', logMeta);\n return;\n }\n const objectDocHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocHandle?.url !== handle.url) {\n log.warn('object was rebound while a document was loading, discarding handle', logMeta);\n return;\n }\n this.onObjectDocumentLoaded.emit({ handle, objectId });\n } catch (err) {\n const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;\n log.warn('failed to load a document', {\n objectId,\n automergeUrl: handle.url,\n retryLoading: shouldRetryLoading,\n err,\n });\n if (shouldRetryLoading) {\n await this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n }\n}\n\nexport interface ObjectDocumentLoaded {\n handle: DocHandle<SpaceDoc>;\n objectId: string;\n}\n\nexport interface DocumentChanges {\n createdObjectIds: string[];\n updatedObjectIds: string[];\n objectsToRebind: string[];\n linkedDocuments: {\n [echoId: string]: AutomergeUrl;\n };\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Message, cbor } from '@dxos/automerge/automerge-repo';\nimport { Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\nimport { ComplexMap, ComplexSet, defaultMap } from '@dxos/util';\n\nimport {\n type EchoReplicator,\n type EchoReplicatorContext,\n type ReplicatorConnection,\n type ShouldAdvertizeParams,\n} from './echo-replicator';\n\n// TODO(dmaretskyi): Move out of @dxos/echo-pipeline.\n\n/**\n * Used to replicate with other peers over the network.\n */\nexport class MeshEchoReplicator implements EchoReplicator {\n private readonly _connections = new Set<MeshReplicatorConnection>();\n /**\n * Using automerge peerId as a key.\n */\n private readonly _connectionsPerPeer = new Map<string, MeshReplicatorConnection>();\n\n /**\n * spaceKey -> deviceKey[]\n */\n private readonly _authorizedDevices = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n private _context: EchoReplicatorContext | null = null;\n\n async connect(context: EchoReplicatorContext): Promise<void> {\n this._context = context;\n }\n\n async disconnect() {\n for (const connection of this._connections) {\n await connection.close();\n }\n this._connections.clear();\n this._connectionsPerPeer.clear();\n\n this._context = null;\n }\n\n createExtension(): AutomergeReplicator {\n invariant(this._context);\n\n const connection: MeshReplicatorConnection = new MeshReplicatorConnection({\n ownPeerId: this._context.peerId,\n onRemoteConnected: async () => {\n log('onRemoteConnected', { peerId: connection.peerId });\n invariant(this._context);\n\n if (this._connectionsPerPeer.has(connection.peerId)) {\n this._context.onConnectionAuthScopeChanged(connection);\n } else {\n this._connectionsPerPeer.set(connection.peerId, connection);\n await connection.enable();\n this._context.onConnectionOpen(connection);\n }\n },\n onRemoteDisconnected: async () => {\n log('onRemoteDisconnected', { peerId: connection.peerId });\n this._context?.onConnectionClosed(connection);\n await connection.disable();\n this._connectionsPerPeer.delete(connection.peerId);\n this._connections.delete(connection);\n },\n shouldAdvertize: async (params: ShouldAdvertizeParams) => {\n log('shouldAdvertize', { peerId: connection.peerId, documentId: params.documentId });\n invariant(this._context);\n try {\n const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);\n if (!spaceKey) {\n log('space key not found for share policy check', {\n peerId: connection.peerId,\n documentId: params.documentId,\n });\n return false;\n }\n\n const authorizedDevices = this._authorizedDevices.get(spaceKey);\n\n if (!connection.remoteDeviceKey) {\n log('device key not found for share policy check', {\n peerId: connection.peerId,\n documentId: params.documentId,\n });\n return false;\n }\n\n const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;\n log('share policy check', {\n localPeer: this._context.peerId,\n remotePeer: connection.peerId,\n documentId: params.documentId,\n deviceKey: connection.remoteDeviceKey,\n spaceKey,\n isAuthorized,\n });\n return isAuthorized;\n } catch (err) {\n log.catch(err);\n return false;\n }\n },\n });\n this._connections.add(connection);\n\n return connection.replicatorExtension;\n }\n\n authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey) {\n log('authorizeDevice', { spaceKey, deviceKey });\n defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);\n for (const connection of this._connections) {\n if (connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {\n this._context?.onConnectionAuthScopeChanged(connection);\n }\n }\n }\n}\n\ntype MeshReplicatorConnectionParams = {\n ownPeerId: string;\n onRemoteConnected: () => Promise<void>;\n onRemoteDisconnected: () => Promise<void>;\n shouldAdvertize: (params: ShouldAdvertizeParams) => Promise<boolean>;\n};\n\nclass MeshReplicatorConnection extends Resource implements ReplicatorConnection {\n public readable: ReadableStream<Message>;\n public writable: WritableStream<Message>;\n public remoteDeviceKey: PublicKey | null = null;\n\n public readonly replicatorExtension: AutomergeReplicator;\n\n private _remotePeerId: string | null = null;\n private _isEnabled = false;\n\n constructor(private readonly _params: MeshReplicatorConnectionParams) {\n super();\n\n let readableStreamController!: ReadableStreamDefaultController<Message>;\n this.readable = new ReadableStream<Message>({\n start: (controller) => {\n readableStreamController = controller;\n this._ctx.onDispose(() => controller.close());\n },\n });\n\n this.writable = new WritableStream<Message>({\n write: async (message: Message, controller) => {\n // TODO(dmaretskyi): Show we block on RPC completing here?\n this.replicatorExtension.sendSyncMessage({ payload: cbor.encode(message) }).catch((err) => {\n controller.error(err);\n });\n },\n });\n\n this.replicatorExtension = new AutomergeReplicator(\n {\n peerId: this._params.ownPeerId,\n },\n {\n onStartReplication: async (info, remotePeerId /** Teleport ID */) => {\n // Note: We store only one extension per peer.\n // There can be a case where two connected peers have more than one teleport connection between them\n // and each of them uses different teleport connections to send messages.\n // It works because we receive messages from all teleport connections and Automerge Repo dedup them.\n // TODO(mykola): Use only one teleport connection per peer.\n\n // TODO(dmaretskyi): Critical bug.\n // - two peers get connected via swarm 1\n // - they get connected via swarm 2\n // - swarm 1 gets disconnected\n // - automerge repo thinks that peer 2 got disconnected even though swarm 2 is still active\n\n this.remoteDeviceKey = remotePeerId;\n\n // Set automerge id.\n this._remotePeerId = info.id;\n\n log('onStartReplication', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n\n await this._params.onRemoteConnected();\n },\n onSyncMessage: async ({ payload }) => {\n if (!this._isEnabled) {\n return;\n }\n const message = cbor.decode(payload) as Message;\n // Note: automerge Repo dedup messages.\n readableStreamController.enqueue(message);\n },\n onClose: async () => {\n if (!this._isEnabled) {\n return;\n }\n await this._params.onRemoteDisconnected();\n },\n },\n );\n }\n\n get peerId(): string {\n invariant(this._remotePeerId != null, 'Remote peer has not connected yet.');\n return this._remotePeerId;\n }\n\n async shouldAdvertize(params: ShouldAdvertizeParams): Promise<boolean> {\n return this._params.shouldAdvertize(params);\n }\n\n /**\n * Start exchanging messages with the remote peer.\n * Call after the remote peer has connected.\n */\n async enable() {\n invariant(this._remotePeerId != null, 'Remote peer has not connected yet.');\n this._isEnabled = true;\n }\n\n /**\n * Stop exchanging messages with the remote peer.\n */\n async disable() {\n this._isEnabled = false;\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAASA,aAAa;AACtB,SAASC,QAAQC,WAAWC,YAAYC,gBAAsC;AAC9E,SACEC,YAMK;AAEP,SAASC,eAA+B;AAGxC,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,iBAAiB;AAE1B,SAASC,0BAA0B;AAOnC,SAASC,aAAa;AACtB,SAASC,iBAAiB;;;ACzB1B,SAASC,SAASC,oBAAoB;AACtC,SAAuBC,sBAAsD;AAC7E,SAASC,sBAAsB;AAC/B,SAASC,iBAAiB;AAE1B,SAASC,WAAW;;;;;;;;;;;;AAWb,IAAMC,qBAAN,cAAiCJ,eAAAA;EAStCK,YAA6BC,SAAmC;AAC9D,UAAK;SADsBA,UAAAA;SARZC,eAAe,oBAAIC,IAAAA;SAInBC,eAAe,oBAAIC,IAAAA;SAC5BC,kBAAkCV,eAAeW;SACxCC,aAAa,IAAIf,QAAAA;EAIlC;EAESgB,QAAQC,QAAgBC,cAA+C;AAC9E,SAAKD,SAASA;AACd,SAAKC,eAAeA;AACpB,SAAKH,WAAWI,KAAI;EACtB;EAESC,KAAKC,SAAwB;AACpC,UAAMC,kBAAkB,KAAKX,aAAaY,IAAIF,QAAQG,QAAQ;AAC9D,QAAI,CAACF,iBAAiB;AACpB,YAAM,IAAIG,MAAM,uBAAA;IAClB;AAGAH,oBAAgBI,OAAOC,MAAMN,OAAAA,EAASO,MAAM,CAACC,QAAAA;AAC3C,UAAIP,gBAAgBQ,QAAQ;AAC1BzB,YAAIuB,MAAMC,KAAAA,QAAAA;;;;;;MACZ;IACF,CAAA;EACF;EAESE,aAAmB;EAE5B;EAEA,MACMC,OAAO;AACX5B,cAAU,KAAKS,oBAAoBV,eAAeW,QAAM,QAAA;;;;;;;;;AACxD,SAAKD,kBAAkBV,eAAe8B;AAEtC5B,QAAI,cAAA,QAAA;;;;;;AACJ,SAAK6B,KAAK,SAAS;MACjBC,SAAS;IACX,CAAA;EACF;EAEA,MACMC,QAAQ;AACZhC,cAAU,KAAKS,oBAAoBV,eAAe8B,MAAI,QAAA;;;;;;;;;AAEtD,eAAWI,cAAc,KAAK5B,cAAc;AAC1C,YAAM4B,WAAWN,WAAU;IAC7B;AACA,SAAKtB,aAAa6B,MAAK;AAEvB,SAAKzB,kBAAkBV,eAAeW;EACxC;EAEA,MAAMyB,gBAAgB;AACpB,UAAM,KAAKxB,WAAWyB,KAAK;MAAEC,SAAS;IAAO,CAAA;EAC/C;EAEA,MACMC,cAAcL,YAA4B;AAC9CjC,cAAU,KAAKS,oBAAoBV,eAAe8B,MAAI,QAAA;;;;;;;;;AACtD7B,cAAU,KAAKa,QAAM,QAAA;;;;;;;;;AACrBb,cAAU,CAAC,KAAKK,aAAakC,IAAIN,UAAAA,GAAAA,QAAAA;;;;;;;;;AAEjC,SAAK5B,aAAamC,IAAIP,UAAAA;AACtB,UAAMA,WAAWrB,QAAQ;MACvBC,QAAQ,KAAKA;MACb4B,kBAAkB,KAAKC,kBAAkBC,KAAK,IAAI;MAClDC,oBAAoB,KAAKC,oBAAoBF,KAAK,IAAI;MACtDG,8BAA8B,KAAKC,8BAA8BJ,KAAK,IAAI;MAC1EK,+BAA+B,KAAK5C,QAAQ4C;IAC9C,CAAA;EACF;EAEA,MACMC,iBAAiBhB,YAA4B;AACjDjC,cAAU,KAAKS,oBAAoBV,eAAe8B,MAAI,QAAA;;;;;;;;;AACtD7B,cAAU,KAAKK,aAAakC,IAAIN,UAAAA,GAAAA,QAAAA;;;;;;;;;AAChC,UAAMA,WAAWN,WAAU;AAC3B,SAAKtB,aAAa6C,OAAOjB,UAAAA;EAC3B;EAEA,MAAMkB,gBAAgBtC,QAAgBuC,QAAiD;AACrF,UAAMC,aAAa,KAAK9C,aAAaY,IAAIN,MAAAA;AACzC,QAAI,CAACwC,YAAY;AACf,aAAO;IACT;AAEA,WAAOA,WAAWA,WAAWF,gBAAgBC,MAAAA;EAC/C;EAEQV,kBAAkBW,YAAkC;AAC1DpD,QAAI,qBAAqB;MAAEY,QAAQwC,WAAWxC;IAAO,GAAA;;;;;;AACrDb,cAAU,CAAC,KAAKO,aAAagC,IAAIc,WAAWxC,MAAM,GAAA,QAAA;;;;;;;;;AAClD,UAAMyC,SAASD,WAAWE,SAASC,UAAS;AAC5C,UAAMlC,SAAS+B,WAAWI,SAASC,UAAS;AAC5C,UAAMxC,kBAAmC;MAAEmC;MAAYC;MAAQhC;MAAQI,QAAQ;IAAK;AACpF,SAAKnB,aAAaoD,IAAIN,WAAWxC,QAAkBK,eAAAA;AAEnD0C,mBAAe,YAAA;AACb,UAAI;AACF,eAAO,MAAM;AAEX,gBAAM,EAAEC,MAAMC,MAAK,IAAK,MAAMR,OAAOS,KAAI;AACzC,cAAIF,MAAM;AACR;UACF;AAEA,eAAK/B,KAAK,WAAWgC,KAAAA;QACvB;MACF,SAASrC,KAAK;AACZ,YAAIP,gBAAgBQ,QAAQ;AAC1BzB,cAAIuB,MAAMC,KAAAA,QAAAA;;;;;;QACZ;MACF;IACF,CAAA;AAEAxB,QAAI,uBAAuB;MAAEY,QAAQwC,WAAWxC;IAAO,GAAA;;;;;;AACvD,SAAKmD,mBAAmBX,UAAAA;EAC1B;;;;;EAMQN,8BAA8BM,YAAkC;AACtEpD,QAAI,iCAAiC;MAAEY,QAAQwC,WAAWxC;IAAO,GAAA;;;;;;AACjE,UAAMoD,QAAQ,KAAK1D,aAAaY,IAAIkC,WAAWxC,MAAM;AACrDb,cAAUiE,OAAAA,QAAAA;;;;;;;;;AACV,SAAKnC,KAAK,qBAAqB;MAAEjB,QAAQwC,WAAWxC;IAAiB,CAAA;AACrE,SAAKmD,mBAAmBX,UAAAA;EAC1B;EAEQR,oBAAoBQ,YAAkC;AAC5DpD,QAAI,qBAAqB;MAAEY,QAAQwC,WAAWxC;IAAO,GAAA;;;;;;AACrD,UAAMoD,QAAQ,KAAK1D,aAAaY,IAAIkC,WAAWxC,MAAM;AACrDb,cAAUiE,OAAAA,QAAAA;;;;;;;;;AAEVA,UAAMvC,SAAS;AACf,SAAKI,KAAK,qBAAqB;MAAEjB,QAAQwC,WAAWxC;IAAiB,CAAA;AAErE,SAAKoD,MAAMX,OAAOY,OAAM,EAAG1C,MAAM,CAACC,QAAQxB,IAAIuB,MAAMC,KAAAA,QAAAA;;;;;;AACpD,SAAKwC,MAAM3C,OAAO6C,MAAK,EAAG3C,MAAM,CAACC,QAAQxB,IAAIuB,MAAMC,KAAAA,QAAAA;;;;;;AAEnD,SAAKlB,aAAa2C,OAAOG,WAAWxC,MAAM;EAC5C;EAEQmD,mBAAmBX,YAAkC;AAC3D,SAAKvB,KAAK,kBAAkB;MAC1BjB,QAAQwC,WAAWxC;MACnBC,cAAc;;QAEZsD,iBAAiB;MACnB;IACF,CAAA;EACF;AACF;;EA7HGvE;GArCUK,mBAAAA,WAAAA,QAAAA,IAAAA;;EAgDVL;GAhDUK,mBAAAA,WAAAA,SAAAA,IAAAA;;EAgEVL;GAhEUK,mBAAAA,WAAAA,iBAAAA,IAAAA;;EAgFVL;GAhFUK,mBAAAA,WAAAA,oBAAAA,IAAAA;;;ACbb,SAASmE,kBAAAA,iBAAgBC,gBAAgB;AAgBlC,IAAMC,wBAAN,cAAoCC,SAAAA;EACzCC,YAA6BC,SAAsC;AACjE,UAAK;SADsBA,UAAAA;EAE7B;EAEA,MAAMC,KAAKC,UAAuD;AAChE,QAAI;AACF,UAAI,KAAKC,oBAAoBC,gBAAeC,MAAM;AAEhD,eAAOC;MACT;AACA,aAAO,MAAM,KAAKN,QAAQO,GAAGC,IAA4BN,UAAU;QAAE,GAAGO;MAAgB,CAAA;IAC1F,SAASC,KAAU;AACjB,UAAIC,uBAAuBD,GAAAA,GAAM;AAC/B,eAAOJ;MACT;AACA,YAAMI;IACR;EACF;EAEA,MAAME,KAAKV,UAAsBW,QAAmC;AAClE,QAAI,KAAKV,oBAAoBC,gBAAeC,MAAM;AAChD,aAAOC;IACT;AACA,UAAMQ,QAAQ,KAAKd,QAAQO,GAAGO,MAAK;AAEnC,UAAM,KAAKd,QAAQe,WAAWC,aAAa;MAAEC,MAAMf;MAAUY;IAAM,CAAA;AACnEA,UAAMI,IAA4BhB,UAAUiB,OAAOC,KAAKP,MAAAA,GAAS;MAC/D,GAAGJ;IACL,CAAA;AACA,UAAMK,MAAMO,MAAK;AAEjB,UAAM,KAAKrB,QAAQe,WAAWO,YAAYpB,QAAAA;EAC5C;EAEA,MAAMqB,OAAOrB,UAAqC;AAChD,QAAI,KAAKC,oBAAoBC,gBAAeC,MAAM;AAChD,aAAOC;IACT;AACA,UAAM,KAAKN,QAAQO,GAAGiB,IAAgBtB,UAAU;MAAE,GAAGO;IAAgB,CAAA;EACvE;EAEA,MAAMgB,UAAUC,WAAyC;AACvD,QAAI,KAAKvB,oBAAoBC,gBAAeC,MAAM;AAChD,aAAO,CAAA;IACT;AACA,UAAMsB,SAAkB,CAAA;AACxB,qBAAiB,CAACC,KAAKC,KAAAA,KAAU,KAAK7B,QAAQO,GAAGuB,SAAiC;MAChFC,KAAKL;MACLM,KAAK;WAAIN;QAAW;;MACpB,GAAGjB;IACL,CAAA,GAAI;AACFkB,aAAOM,KAAK;QACVL;QACAM,MAAML;MACR,CAAA;IACF;AACA,WAAOF;EACT;EAEA,MAAMQ,YAAYT,WAAsC;AACtD,QAAI,KAAKvB,oBAAoBC,gBAAeC,MAAM;AAChD,aAAOC;IACT;AACA,UAAMQ,QAAQ,KAAKd,QAAQO,GAAGO,MAAK;AAEnC,qBAAiB,CAACc,GAAAA,KAAQ,KAAK5B,QAAQO,GAAGuB,SAAiC;MACzEC,KAAKL;MACLM,KAAK;WAAIN;QAAW;;MACpB,GAAGjB;IACL,CAAA,GAAI;AACFK,YAAMU,IAAgBI,KAAK;QAAE,GAAGnB;MAAgB,CAAA;IAClD;AACA,UAAMK,MAAMO,MAAK;EACnB;AACF;AAEA,IAAMe,aAAgE;EACpEC,QAAQ,CAACT,QACPT,OAAOC,KAAKQ,IAAIU,IAAI,CAACC,MAAMA,EAAEC,WAAW,KAAK,KAAA,EAAOA,WAAW,KAAK,KAAA,CAAA,EAAQC,KAAK,GAAA,CAAA;EACnFC,QAAQ,CAACd,QACPT,OAAOC,KAAKQ,GAAAA,EACTe,SAAQ,EACRC,MAAM,GAAA,EACNN,IAAI,CAACC,MAAMA,EAAEC,WAAW,OAAO,GAAA,EAAKA,WAAW,OAAO,GAAA,CAAA;EAC3DK,QAAQ;AACV;AAEO,IAAMpC,kBAAkB;EAC7BqC,aAAaV;EACbW,eAAe;AACjB;AAEA,IAAMpC,yBAAyB,CAACD,QAAsBA,IAAIsC,SAAS;;;AChHnE,SAASC,WAAAA,gBAAe;AACxB,SAASC,kBAAAA,iBAA2CC,YAAY;AAChE,SAASC,cAAc;AACvB,SAASC,aAAAA,kBAAiB;;AAYnB,IAAMC,0BAAN,cAAsCJ,gBAAAA;EAAtC;;AACYK,kBAAuC,oBAAIC,IAAAA;AAa3CC,sBAAa,IAAIR,SAAAA;AAC1BS,wBAAwB;;;;;EAThCC,QAAQ;AAGN,SAAKC,KAAK,SAAS;MACjBC,SAAS;IACX,CAAA;EACF;;;;;;EAUSC,QAAQC,QAAsB;AACrC,SAAKA,SAASA;AACd,SAAKL,eAAe;AACpB,SAAKD,WAAWO,KAAI;EAEtB;EAESC,KAAKC,SAAwB;AACpC,UAAMC,OAAO,KAAKZ,OAAOa,IAAIF,QAAQG,QAAQ;AAC7ChB,IAAAA,WAAUc,MAAM,mBAAA;;;;;;;;;AAChBA,SAAKF,KAAKC,OAAAA;EACZ;EAEA,MAAMI,QAAQ;AACZ,SAAKf,OAAOgB,QAAQ,CAACJ,SAASA,KAAKK,WAAU,CAAA;AAC7C,SAAKZ,KAAK,OAAA;EACZ;EAESY,aAAmB;EAG5B;EAEA,MAAMC,gBAA+B;AACnC,UAAM,KAAKhB,WAAWiB,KAAK;MAAEC,SAAS;IAAO,CAAA;EAC/C;EAEAC,SAAS,EAAEC,IAAIC,YAAW,GAA+C;AACvE,UAAMf,SAAS,KAAKgB,WAAWF,EAAAA;AAE/B,WAAO,IAAIzB,OAAO,CAAC,EAAE4B,MAAMV,MAAK,MAAE;AAChCjB,MAAAA,WAAU,CAAC,KAAKE,OAAO0B,IAAIlB,MAAAA,GAAS,2BAAA;;;;;;;;;AACpC,WAAKR,OAAO2B,IAAInB,QAAQ;QACtBoB,WAAW;QACXlB,MAAM,CAACC,YAAAA;AACLc,eAAK;YACHF,aAAa3B,KAAKiC,OAAOlB,OAAAA;UAC3B,CAAA;QACF;QACAM,YAAY,MAAA;AACV,eAAKjB,OAAO8B,OAAOtB,MAAAA;AACnBO,gBAAAA;AACA,eAAKV,KAAK,qBAAqB;YAC7BG;UACF,CAAA;QACF;MACF,CAAA;AAEAV,MAAAA,WAAU,KAAKK,cAAY,QAAA;;;;;;;;;AAC3B,WAAKE,KAAK,kBAAkB;QAC1B0B,cAAc,CAAC;QACfvB;MACF,CAAA;IACF,CAAA;EACF;EAEA,MAAMwB,gBAAgB,EAAEV,IAAIC,YAAW,GAAoC;AACzEzB,IAAAA,WAAU,KAAKK,cAAY,QAAA;;;;;;;;;AAC3B,UAAMQ,UAAUf,KAAKqC,OAAOV,WAAAA;AAC5B,SAAKlB,KAAK,WAAWM,OAAAA;EACvB;EAEA,MAAMuB,cAAiC;AACrCpC,IAAAA,WAAU,KAAKK,cAAY,QAAA;;;;;;;;;AAC3BL,IAAAA,WAAU,KAAKU,QAAQ,oBAAA;;;;;;;;;AACvB,WAAO;MACLA,QAAQ,KAAKA;IACf;EACF;EAEQgB,WAAWF,IAAoB;AACrC,WAAOA;EACT;AACF;;;;;;;;;;;;;;AHpEO,IAAMa,gBAAN,MAAMA;EAcXC,YAAY,EAAEC,IAAIC,mBAAkB,GAAyB;AAZ5CC,gBAAO,IAAIC,QAAAA;AACXC,+BAAsB,IAAIC,mBAAmB;MAC5DC,+BAA+B,KAAKC,+BAA+BC,KAAK,IAAI;IAC9E,CAAA;AAUE,SAAKC,WAAW,IAAIC,sBAAsB;MACxCV;MACAW,WAAW;QACTC,YAAY,OAAOC,WAAW,KAAKC,YAAYD,MAAAA;QAC/CE,WAAW,YAAY,KAAKC,WAAU;MACxC;IACF,CAAA;AACA,SAAKC,sBAAsBhB;EAC7B;EAEA,MAAMiB,OAAO;AAEX,SAAKC,UAAU,QAAQC,UAAUC,OAAM,EAAGC,MAAK,CAAA;AAE/C,UAAM,KAAKb,SAASS,OAAI;AACxB,SAAKK,iBAAiB,IAAIC,wBAAAA;AAG1B,SAAKC,QAAQ,IAAIC,KAAK;MACpBC,QAAQ,KAAKR;MACbS,aAAa,KAAKC,aAAarB,KAAK,IAAI;MACxCsB,SAAS,KAAKrB;MACdsB,SAAS;;QAEP,KAAKR;;QAEL,KAAKnB;;IAET,CAAA;AAEA,SAAKmB,eAAeS,MAAK;AACzB,UAAM,KAAK5B,oBAAoBc,KAAI;AACnC,UAAM,KAAKK,eAAeU,cAAa;AACvC,UAAM,KAAK7B,oBAAoB6B,cAAa;EAC9C;EAEA,MAAMC,QAAQ;AACZ,UAAM,KAAKzB,SAASyB,QAAK;AACzB,UAAM,KAAKX,eAAeW,MAAK;AAC/B,UAAM,KAAK9B,oBAAoB8B,MAAK;AACpC,UAAM,KAAKhC,KAAKiC,QAAO;EACzB;EAEA,IAAIC,OAAa;AACf,WAAO,KAAKX;EACd;EAEA,MAAMY,cAAcC,YAA4B;AAC9C,UAAM,KAAKlC,oBAAoBiC,cAAcC,UAAAA;EAC/C;EAEA,MAAMC,iBAAiBD,YAA4B;AACjD,UAAM,KAAKlC,oBAAoBmC,iBAAiBD,UAAAA;EAClD;;;;;EAMA,MAAcT,aACZF,QACAa,YACkB;AAClB,QAAIb,OAAOc,WAAW,SAAA,GAAY;AAChC,aAAO;IACT;AAEA,QAAI,CAACD,YAAY;AACf,aAAO;IACT;AAEA,UAAME,eAAe,KAAKN,KAAKO,qBAAqBhB,MAAAA;AACpD,QAAKe,cAAsBE,oBAAoB,sBAAsB;AACnE,aAAO,KAAKxC,oBAAoByC,gBAAgBlB,QAAQ;QAAEa;MAAW,CAAA;IACvE;AAEA,WAAO;EACT;EAEA,MAAc1B,YAAY,EAAEgC,MAAMC,MAAK,GAAsB;AAC3D,UAAMC,SAAS,KAAKvB,MAAMwB,QAAQH,KAAK,CAAA,CAAE;AACzC,QAAI,CAACE,QAAQ;AACX;IACF;AACA,UAAME,MAAMF,OAAOG,QAAO;AAC1B,QAAI,CAACD,KAAK;AACR;IACF;AAEA,UAAME,WAAWC,mBAAmBH,GAAAA,KAAQI;AAE5C,UAAMC,oBAAoBC,SAASN,GAAAA;AAEnC,UAAMO,YAAYC,OAAOC,KAAKT,IAAIU,WAAW,CAAC,CAAA;AAC9C,UAAMC,aAAaJ,UAAUK,IAAI,CAACC,aAChCC,mBAAmBC,OAAO;MAAEzB,YAAYQ,OAAOR;MAAYuB;MAAUX;IAAS,CAAA,CAAA;AAEhF,UAAMc,eAAe,IAAIC,IAAIN,WAAWC,IAAI,CAACM,OAAO;MAACA;MAAIb;KAAkB,CAAA;AAC3E,SAAKtC,oBAAoBoD,UAAUH,cAAcnB,KAAAA;EACnD;;;;EAKA,MAAc/B,aAAa;AACzB,SAAKC,oBAAoBqD,kBAAiB;EAC5C;EAGQC,iBAAiB;AACvB,WAAOC,UAAU,KAAK/C,MAAMwB,SAAS,CAACD,YAAY;MAChDyB,OAAOzB,OAAOyB;MACdC,QAAQ,CAAC,CAAC1B,OAAOG,QAAO;MACxBwB,OAAO3B,OAAOG,QAAO,IAAKyB,UAAUpB,SAASR,OAAOG,QAAO,CAAA,IAAM;MACjE0B,MACE7B,OAAOG,QAAO,KACdqB,UAAUxB,OAAOG,QAAO,GAAI,CAAC2B,OAAOC,QAAAA;AAClC,YAAI;AACF,kBAAQA,KAAAA;YACN,KAAK;YACL,KAAK;AACH,qBAAOD;YACT,KAAK;AACH,qBAAOpB,OAAOC,KAAKmB,KAAAA;YACrB;AACE,qBAAO,GAAGA,KAAAA;UACd;QACF,SAASE,KAAK;AACZ,iBAAO,GAAGA,GAAAA;QACZ;MACF,CAAA;IACJ,EAAA;EACF;EAGQC,kBAAkB;AACxB,WAAO,KAAKxD,MAAMyD;EACpB;EAEA,MAAc3E,+BAA+BiC,YAA+C;AAC1F,UAAMU,MAAM,KAAKzB,MAAMwB,QAAQT,UAAAA,GAAoBW,QAAAA;AACnD,QAAI,CAACD,KAAK;AACR,aAAO;IACT;AAEA,UAAMiC,cAAc9B,mBAAmBH,GAAAA;AACvC,QAAI,CAACiC,aAAa;AAChB,aAAO;IACT;AAEA,WAAO/D,UAAUgE,KAAKD,WAAAA;EACxB;;;;EAKA,MACME,MAAM,EAAEC,OAAM,GAAiC;AAEnD,UAAMC,QAAQC,IACZF,QAAQxB,IAAI,OAAO,EAAEa,OAAOnC,WAAU,MAAE;AACtCiD,MAAAA,WAAUd,OAAO,gCAAA;;;;;;;;;AACjB,YAAM3B,SAAS,KAAKZ,KAAKa,QAAQT,UAAAA,KAA6B,KAAKf,MAAMiE,KAAKlD,UAAAA;AAC9E,YAAMmD,aAAa3C,QAAQ2B,KAAAA;IAC7B,CAAA,KAAM,CAAA,CAAE;AAGV,UAAM,KAAKlD,MAAM4D,MAAMC,QAAQxB,IAAI,CAAC,EAAEtB,WAAU,MAAOA,UAAAA,CAAAA;EACzD;EAEAoD,SAASC,SAAoD;AAC3D,WAAO,KAAKtE,eAAeqE,SAASC,OAAAA;EACtC;EAEAC,gBAAgBD,SAAyC;AACvD,WAAO,KAAKtE,eAAeuE,gBAAgBD,OAAAA;EAC7C;EAEA,MAAME,cAAiC;AACrC,WAAO,KAAKxE,eAAewE,YAAW;EACxC;AACF;;EAzLGC,MAAMC,KAAI;GAXAnG,cAAAA,WAAAA,WAAAA,MAAAA;;EA2HVkG,MAAMC,KAAK;IAAEC,OAAO;EAAK,CAAA;GA3HfpG,cAAAA,WAAAA,kBAAAA,IAAAA;;EAqJVkG,MAAMC,KAAK;IAAEC,OAAO;EAAK,CAAA;GArJfpG,cAAAA,WAAAA,mBAAAA,IAAAA;;EA2KVkG,MAAMG,KAAK;IAAEC,uBAAuB;EAAK,CAAA;GA3K/BtG,cAAAA,WAAAA,SAAAA,IAAAA;AAAAA,gBAAAA,cAAAA;EADZkG,MAAMK,SAAQ;GACFvG,aAAAA;AAsMN,IAAMuD,qBAAqB,CAACH,QAAAA;AAEjC,QAAMoD,cAAcpD,IAAIqD,QAAQnD,YAAYF,IAAIsD;AAChD,MAAIF,eAAe,MAAM;AACvB,WAAO;EACT;AAEA,SAAOG,OAAOH,WAAAA;AAChB;AAEA,IAAMX,eAAe,OAAO3C,QAA6B2B,UAAAA;AACvD,QAAM3B,OAAO0D,UAAS;AACtB,QAAMC,mBAAmB,IAAIC,IAAIjC,KAAAA;AAEjC,QAAMkC,MAAMC,KAAuC9D,QAAQ,QAAA,EAAU+D,iBAAiB,MAAA;AAEpF,eAAWC,cAAcL,iBAAiBM,OAAM,GAAI;AAClD,UAAIC,qBAAqBlE,OAAOG,QAAO,GAAI6D,UAAAA,GAAa;AACtDL,yBAAiBQ,OAAOH,UAAAA;MAC1B;IACF;AAEA,QAAIL,iBAAiBS,SAAS,GAAG;AAC/B,aAAO;IACT;AACA,WAAO;EACT,CAAA;AACF;AAEA,IAAMF,uBAAuB,CAAChE,KAAe8D,eAAAA;AAC3C,SAAO,CAAC,CAACK,WAAWnE,GAAAA,EAAKoE,gBAAgBN,UAAAA;AAC3C;;;AI/QA,SAASO,SAAAA,cAAa;AAEtB,SAASC,yBAAuC;AAChD,SAASC,wBAAwB;AACjC,SAAyCC,uBAAuB;AAChE,SAASC,aAAAA,kBAAiB;AAE1B,SAASC,OAAAA,YAAW;AACpB,SAASC,SAAAA,cAAa;;;;;;;;;;;;AA0Bf,IAAMC,8BAAN,MAAMA;EAcXC,YACmBC,UACAC,OAEAC,WACjB;SAJiBF,WAAAA;SACAC,QAAAA;SAEAC,YAAAA;SAjBXC,sBAAkD;SAIzCC,yBAAyB,oBAAIC,IAAAA;SAK7BC,8BAA8B,oBAAIC,IAAAA;SAEnCC,yBAAyB,IAAIjB,OAAAA;EAO1C;EAEHkB,gBAAuC;AACrC,WAAO,KAAKN,uBAAuB,OAC/B;MAAC,KAAKA;SAAwB,IAAII,IAAI,KAAKH,uBAAuBM,OAAM,CAAA;QACxE,CAAA;EACN;EAEA,MACaC,uBAAuBC,KAAcC,YAAuC;AACvF,QAAI,KAAKV,uBAAuB,MAAM;AACpC;IACF;AACA,QAAI,CAACU,WAAWC,SAAS;AACvBlB,MAAAA,KAAImB,MAAM,mCAAmC;QAAEC,SAAS,KAAKhB;MAAS,GAAA;;;;;;AACtE,WAAKiB,qCAAqCL,GAAAA;IAC5C,OAAO;AACL,YAAMM,oBAAoB,MAAM,KAAKC,eAAeP,KAAKC,WAAWC,OAAO;AAC3E,YAAMM,MAAMF,kBAAkBG,QAAO;AACrC1B,MAAAA,WAAUyB,KAAAA,QAAAA;;;;;;;;;AACV,UAAIA,IAAIE,UAAU,MAAM;AACtB,aAAKC,eAAeL,iBAAAA;MACtB;AACA,WAAKf,sBAAsBe;IAC7B;EACF;EAEOM,mBAAmBC,gBAAmC;AAC3D,UAAMC,YAAYC,MAAMC,QAAQH,cAAAA,IAAkBA,iBAAiB;MAACA;;AACpE,QAAII,gBAAgB;AACpB,UAAMC,aAAgC,CAAC;AACvC,eAAWC,YAAYL,WAAW;AAChC/B,MAAAA,WAAU,KAAKQ,qBAAmB,QAAA;;;;;;;;;AAClC,UAAI,KAAKC,uBAAuB4B,IAAID,QAAAA,KAAa,KAAKzB,4BAA4B0B,IAAID,QAAAA,GAAW;AAC/F;MACF;AACA,YAAME,eAAe,KAAK9B,oBAAoBkB,QAAO;AACrD1B,MAAAA,WAAUsC,cAAAA,QAAAA;;;;;;;;;AACV,YAAMC,eAAeD,aAAaE,SAAS,CAAC,GAAGJ,QAAAA;AAC/C,UAAIG,eAAe,MAAM;AACvB,aAAK5B,4BAA4B8B,IAAIL,QAAAA;AACrCnC,QAAAA,KAAIyC,KAAK,sDAAsD;UAAEN;QAAS,GAAA;;;;;;MAC5E,OAAO;AACLD,mBAAWC,QAAAA,IAAYG;AACvBL,wBAAgB;MAClB;IACF;AACA,QAAIA,eAAe;AACjB,WAAKS,mBAAmBR,UAAAA;IAC1B;EACF;EAEOS,qBAAqBJ,OAA2B;AACrD,QAAI,CAACA,OAAO;AACV;IACF;AACA,UAAMK,oBAAoBC,OAAOC,QAAQP,KAAAA,EAAOQ,OAAO,CAAC,CAACZ,QAAAA,MACvD,KAAKzB,4BAA4B0B,IAAID,QAAAA,CAAAA;AAEvC,SAAKO,mBAAmBG,OAAOG,YAAYJ,iBAAAA,CAAAA;AAC3CA,sBAAkBK,QAAQ,CAAC,CAACd,QAAAA,MAAc,KAAKzB,4BAA4BwC,OAAOf,QAAAA,CAAAA;EACpF;EAEOgB,wBAA6C;AAClDpD,IAAAA,WAAU,KAAKQ,qBAAmB,QAAA;;;;;;;;;AAClC,WAAO,KAAKA;EACd;EAEO6C,wBAAwBjB,UAAuC;AACpEpC,IAAAA,WAAU,KAAKQ,qBAAmB,QAAA;;;;;;;;;AAClC,UAAM8C,iBAAiB,KAAKhD,MAAMiD,OAAiB;MACjDC,SAASzD,gBAAgB0D;IAC3B,CAAA;AACA,SAAK7B,eAAe0B,cAAAA;AACpB,SAAKI,wBAAwBJ,gBAAgBlB,QAAAA;AAC7C,SAAK5B,oBAAoBmD,OAAO,CAACC,WAAAA;AAC/BA,aAAOpB,UAAU,CAAC;AAClBoB,aAAOpB,MAAMJ,QAAAA,IAAYkB,eAAeO;IAC1C,CAAA;AACA,WAAOP;EACT;EAEOI,wBAAwBI,QAA6B1B,UAAkB;AAC5E,SAAK3B,uBAAuBsD,IAAI3B,UAAU0B,MAAAA;EAC5C;EAEOE,wBAAkC;AACvC,UAAMC,qBAAqB;SAAI,KAAKxD,uBAAuByD,KAAI;;AAC/D,SAAKzD,uBAAuB0D,MAAK;AACjC,SAAK3D,sBAAsB;AAC3B,WAAOyD;EACT;EAEQtB,mBAAmBH,OAA2B;AACpD,QAAI,CAACA,OAAO;AACV;IACF;AACA,eAAW,CAACJ,UAAUgC,YAAAA,KAAiBtB,OAAOC,QAAQP,KAAAA,GAAQ;AAC5D,YAAM6B,UAAU;QAAEjC;QAAUgC;MAAa;AACzC,YAAME,uBAAuB,KAAK7D,uBAAuB8D,IAAInC,QAAAA;AAC7D,UAAIkC,wBAAwB,QAAQA,qBAAqBT,QAAQO,cAAc;AAC7EnE,QAAAA,KAAIuE,KAAK,qEAAqE;UAC5E,GAAGH;UACHI,mBAAmBH,qBAAqBT;QAC1C,GAAA;;;;;;AACA;MACF;AACA,UAAIS,sBAAsBT,QAAQO,cAAc;AAC9CnE,QAAAA,KAAIuE,KAAK,sCAAsCH,SAAAA;;;;;;AAC/C;MACF;AACA,YAAMP,SAAS,KAAKxD,MAAMoE,KAAeN,YAAAA;AACzCnE,MAAAA,KAAI0E,MAAM,8BAA8BN,SAAAA;;;;;;AACxC,WAAK5D,uBAAuBsD,IAAI3B,UAAU0B,MAAAA;AAC1C,WAAK,KAAKc,4BAA4Bd,QAAQ1B,QAAAA;IAChD;EACF;EAEA,MAAcZ,eAAeP,KAAc4C,KAAa;AACtD,UAAMgB,YAAY,KAAKvE,MAAMoE,KAAeb,GAAAA;AAC5C,WAAO,MAAM;AACX,UAAI;AACF,cAAM/D,iBAAiB,KAAO,kDAAkD,YAAA;AAC9E,gBAAMD,kBAAkBoB,KAAK4D,UAAUC,UAAS,CAAA;QAClD,CAAA;AACA;MACF,SAASC,KAAK;AACZ,YAAI,GAAGA,GAAAA,GAAMC,SAAS,SAAA,GAAY;AAChC/E,UAAAA,KAAIyC,KAAK,cAAc;YAAEuC,IAAIJ,UAAUK;YAAYC,OAAON,UAAUM;UAAM,GAAA;;;;;;AAC1E;QACF;AAEA,cAAMJ;MACR;IACF;AAEA,QAAIF,UAAUM,UAAU,eAAe;AACrC,YAAM,IAAIC,MAAM,mCAAA;IAClB;AAEA,WAAOP;EACT;EAEQvD,qCAAqCL,KAAc;AACzD,UAAM4D,YAAY,KAAKvE,MAAMiD,OAAM;AACnC,SAAK/C,sBAAsBqE;AAC3B5D,QAAIoE,UAAU,MAAA;AACZR,gBAAU1B,OAAM;AAChB,WAAK3C,sBAAsB;IAC7B,CAAA;EACF;EAEQoB,eAAekC,QAA6B;AAClDA,WAAOH,OAAO,CAACC,WAAAA;AACbA,aAAOjC,WAAW;QAAE2D,UAAU,KAAK/E,UAAUgF,MAAK;MAAG;AACrD3B,aAAOjC,OAAO2D,WAAW,KAAK/E,UAAUgF,MAAK;IAC/C,CAAA;EACF;EAEA,MAAcX,4BAA4Bd,QAA6B1B,UAAkB;AACvF,QAAI;AACF,YAAM0B,OAAOrC,IAAI;QAAC;OAAQ;AAC1B,YAAM4C,UAAU;QAAEjC;QAAUoD,QAAQ1B,OAAOD;MAAI;AAC/C,UAAI,KAAKhD,uBAAuB4E,cAAa,MAAO,GAAG;AACrDxF,QAAAA,KAAIyC,KAAK,oDAAoD2B,SAAAA;;;;;;AAC7D;MACF;AACA,YAAMqB,kBAAkB,KAAKjF,uBAAuB8D,IAAInC,QAAAA;AACxD,UAAIsD,iBAAiB7B,QAAQC,OAAOD,KAAK;AACvC5D,QAAAA,KAAIuE,KAAK,sEAAsEH,SAAAA;;;;;;AAC/E;MACF;AACA,WAAKxD,uBAAuB8E,KAAK;QAAE7B;QAAQ1B;MAAS,CAAA;IACtD,SAAS2C,KAAK;AACZ,YAAMa,qBAAqB,KAAK/E,uBAAuB4E,cAAa,IAAK;AACzExF,MAAAA,KAAIuE,KAAK,6BAA6B;QACpCpC;QACAgC,cAAcN,OAAOD;QACrBgC,cAAcD;QACdb;MACF,GAAA;;;;;;AACA,UAAIa,oBAAoB;AACtB,cAAM,KAAKhB,4BAA4Bd,QAAQ1B,QAAAA;MACjD;IACF;EACF;AACF;;EAlLGlC,OAAM4F,KAAK;IAAEC,uBAAuB;EAAK,CAAA;GA3B/B5F,4BAAAA,WAAAA,0BAAAA,IAAAA;AAAAA,8BAAAA,cAAAA;EADZD,OAAM8F,SAAQ;GACF7F,2BAAAA;;;AClCb,SAAuB8F,QAAAA,aAAY;AACnC,SAASC,YAAAA,iBAAgB;AACzB,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,2BAA2B;AACpC,SAASC,YAAYC,YAAYC,kBAAkB;;AAc5C,IAAMC,qBAAN,MAAMA;EAAN;AACYC,wBAAe,oBAAIC,IAAAA;AAInBC;;;+BAAsB,oBAAIC,IAAAA;AAK1BC;;;8BAAqB,IAAIR,WAA6CH,WAAUY,IAAI;AAE7FC,oBAAyC;;EAEjD,MAAMC,QAAQC,SAA+C;AAC3D,SAAKF,WAAWE;EAClB;EAEA,MAAMC,aAAa;AACjB,eAAWC,cAAc,KAAKV,cAAc;AAC1C,YAAMU,WAAWC,MAAK;IACxB;AACA,SAAKX,aAAaY,MAAK;AACvB,SAAKV,oBAAoBU,MAAK;AAE9B,SAAKN,WAAW;EAClB;EAEAO,kBAAuC;AACrCrB,IAAAA,WAAU,KAAKc,UAAQ,QAAA;;;;;;;;;AAEvB,UAAMI,aAAuC,IAAII,yBAAyB;MACxEC,WAAW,KAAKT,SAASU;MACzBC,mBAAmB,YAAA;AACjBvB,QAAAA,KAAI,qBAAqB;UAAEsB,QAAQN,WAAWM;QAAO,GAAA;;;;;;AACrDxB,QAAAA,WAAU,KAAKc,UAAQ,QAAA;;;;;;;;;AAEvB,YAAI,KAAKJ,oBAAoBgB,IAAIR,WAAWM,MAAM,GAAG;AACnD,eAAKV,SAASa,6BAA6BT,UAAAA;QAC7C,OAAO;AACL,eAAKR,oBAAoBkB,IAAIV,WAAWM,QAAQN,UAAAA;AAChD,gBAAMA,WAAWW,OAAM;AACvB,eAAKf,SAASgB,iBAAiBZ,UAAAA;QACjC;MACF;MACAa,sBAAsB,YAAA;AACpB7B,QAAAA,KAAI,wBAAwB;UAAEsB,QAAQN,WAAWM;QAAO,GAAA;;;;;;AACxD,aAAKV,UAAUkB,mBAAmBd,UAAAA;AAClC,cAAMA,WAAWe,QAAO;AACxB,aAAKvB,oBAAoBwB,OAAOhB,WAAWM,MAAM;AACjD,aAAKhB,aAAa0B,OAAOhB,UAAAA;MAC3B;MACAiB,iBAAiB,OAAOC,WAAAA;AACtBlC,QAAAA,KAAI,mBAAmB;UAAEsB,QAAQN,WAAWM;UAAQa,YAAYD,OAAOC;QAAW,GAAA;;;;;;AAClFrC,QAAAA,WAAU,KAAKc,UAAQ,QAAA;;;;;;;;;AACvB,YAAI;AACF,gBAAMwB,WAAW,MAAM,KAAKxB,SAASyB,8BAA8BH,OAAOC,UAAU;AACpF,cAAI,CAACC,UAAU;AACbpC,YAAAA,KAAI,8CAA8C;cAChDsB,QAAQN,WAAWM;cACnBa,YAAYD,OAAOC;YACrB,GAAA;;;;;;AACA,mBAAO;UACT;AAEA,gBAAMG,oBAAoB,KAAK5B,mBAAmB6B,IAAIH,QAAAA;AAEtD,cAAI,CAACpB,WAAWwB,iBAAiB;AAC/BxC,YAAAA,KAAI,+CAA+C;cACjDsB,QAAQN,WAAWM;cACnBa,YAAYD,OAAOC;YACrB,GAAA;;;;;;AACA,mBAAO;UACT;AAEA,gBAAMM,eAAeH,mBAAmBd,IAAIR,WAAWwB,eAAe,KAAK;AAC3ExC,UAAAA,KAAI,sBAAsB;YACxB0C,WAAW,KAAK9B,SAASU;YACzBqB,YAAY3B,WAAWM;YACvBa,YAAYD,OAAOC;YACnBS,WAAW5B,WAAWwB;YACtBJ;YACAK;UACF,GAAA;;;;;;AACA,iBAAOA;QACT,SAASI,KAAK;AACZ7C,UAAAA,KAAI8C,MAAMD,KAAAA,QAAAA;;;;;;AACV,iBAAO;QACT;MACF;IACF,CAAA;AACA,SAAKvC,aAAayC,IAAI/B,UAAAA;AAEtB,WAAOA,WAAWgC;EACpB;EAEAC,gBAAgBb,UAAqBQ,WAAsB;AACzD5C,IAAAA,KAAI,mBAAmB;MAAEoC;MAAUQ;IAAU,GAAA;;;;;;AAC7CxC,eAAW,KAAKM,oBAAoB0B,UAAU,MAAM,IAAIjC,WAAWJ,WAAUY,IAAI,CAAA,EAAGoC,IAAIH,SAAAA;AACxF,eAAW5B,cAAc,KAAKV,cAAc;AAC1C,UAAIU,WAAWwB,mBAAmBxB,WAAWwB,gBAAgBU,OAAON,SAAAA,GAAY;AAC9E,aAAKhC,UAAUa,6BAA6BT,UAAAA;MAC9C;IACF;EACF;AACF;AASA,IAAMI,2BAAN,cAAuCvB,UAAAA;EAUrCsD,YAA6BC,SAAyC;AACpE,UAAK;SADsBA,UAAAA;SAPtBZ,kBAAoC;SAInCa,gBAA+B;SAC/BC,aAAa;AAKnB,QAAIC;AACJ,SAAKC,WAAW,IAAIC,eAAwB;MAC1CC,OAAO,CAACC,eAAAA;AACNJ,mCAA2BI;AAC3B,aAAKC,KAAKC,UAAU,MAAMF,WAAW1C,MAAK,CAAA;MAC5C;IACF,CAAA;AAEA,SAAK6C,WAAW,IAAIC,eAAwB;MAC1CC,OAAO,OAAOC,SAAkBN,eAAAA;AAE9B,aAAKX,oBAAoBkB,gBAAgB;UAAEC,SAASvE,MAAKwE,OAAOH,OAAAA;QAAS,CAAA,EAAGnB,MAAM,CAACD,QAAAA;AACjFc,qBAAWU,MAAMxB,GAAAA;QACnB,CAAA;MACF;IACF,CAAA;AAEA,SAAKG,sBAAsB,IAAI/C,oBAC7B;MACEqB,QAAQ,KAAK8B,QAAQ/B;IACvB,GACA;MACEiD,oBAAoB,OAAOC,MAAMC,iBAA6B;AAa5D,aAAKhC,kBAAkBgC;AAGvB,aAAKnB,gBAAgBkB,KAAKE;AAE1BzE,QAAAA,KAAI,sBAAsB;UAAEyE,IAAIF,KAAKE;UAAIC,YAAY,KAAKpD;UAAQkD,cAAcA,aAAaG,MAAK;QAAG,GAAA;;;;;;AAErG,cAAM,KAAKvB,QAAQ7B,kBAAiB;MACtC;MACAqD,eAAe,OAAO,EAAET,QAAO,MAAE;AAC/B,YAAI,CAAC,KAAKb,YAAY;AACpB;QACF;AACA,cAAMW,UAAUrE,MAAKiF,OAAOV,OAAAA;AAE5BZ,iCAAyBuB,QAAQb,OAAAA;MACnC;MACAc,SAAS,YAAA;AACP,YAAI,CAAC,KAAKzB,YAAY;AACpB;QACF;AACA,cAAM,KAAKF,QAAQvB,qBAAoB;MACzC;IACF,CAAA;EAEJ;EAEA,IAAIP,SAAiB;AACnBxB,IAAAA,WAAU,KAAKuD,iBAAiB,MAAM,sCAAA;;;;;;;;;AACtC,WAAO,KAAKA;EACd;EAEA,MAAMpB,gBAAgBC,QAAiD;AACrE,WAAO,KAAKkB,QAAQnB,gBAAgBC,MAAAA;EACtC;;;;;EAMA,MAAMP,SAAS;AACb7B,IAAAA,WAAU,KAAKuD,iBAAiB,MAAM,sCAAA;;;;;;;;;AACtC,SAAKC,aAAa;EACpB;;;;EAKA,MAAMvB,UAAU;AACd,SAAKuB,aAAa;EACpB;AACF;",
6
+ "names": ["Event", "next", "automerge", "getBackend", "getHeads", "Repo", "Context", "invariant", "PublicKey", "objectPointerCodec", "trace", "mapValues", "Trigger", "synchronized", "NetworkAdapter", "LifecycleState", "invariant", "log", "EchoNetworkAdapter", "constructor", "_params", "_replicators", "Set", "_connections", "Map", "_lifecycleState", "CLOSED", "_connected", "connect", "peerId", "peerMetadata", "wake", "send", "message", "connectionEntry", "get", "targetId", "Error", "writer", "write", "catch", "err", "isOpen", "disconnect", "open", "OPEN", "emit", "network", "close", "replicator", "clear", "whenConnected", "wait", "timeout", "addReplicator", "has", "add", "onConnectionOpen", "_onConnectionOpen", "bind", "onConnectionClosed", "_onConnectionClosed", "onConnectionAuthScopeChanged", "_onConnectionAuthScopeChanged", "getContainingSpaceForDocument", "removeReplicator", "delete", "shouldAdvertize", "params", "connection", "reader", "readable", "getReader", "writable", "getWriter", "set", "queueMicrotask", "done", "value", "read", "_emitPeerCandidate", "entry", "cancel", "abort", "dxos_peerSource", "LifecycleState", "Resource", "LevelDBStorageAdapter", "Resource", "constructor", "_params", "load", "keyArray", "_lifecycleState", "LifecycleState", "OPEN", "undefined", "db", "get", "encodingOptions", "err", "isLevelDbNotFoundError", "save", "binary", "batch", "callbacks", "beforeSave", "path", "put", "Buffer", "from", "write", "afterSave", "remove", "del", "loadRange", "keyPrefix", "result", "key", "value", "iterator", "gte", "lte", "push", "data", "removeRange", "keyEncoder", "encode", "map", "k", "replaceAll", "join", "decode", "toString", "split", "format", "keyEncoding", "valueEncoding", "code", "Trigger", "NetworkAdapter", "cbor", "Stream", "invariant", "LocalHostNetworkAdapter", "_peers", "Map", "_connected", "_isConnected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "peer", "get", "targetId", "close", "forEach", "disconnect", "whenConnected", "wait", "timeout", "syncRepo", "id", "syncMessage", "_getPeerId", "next", "has", "set", "connected", "encode", "delete", "peerMetadata", "sendSyncMessage", "decode", "getHostInfo", "AutomergeHost", "constructor", "db", "indexMetadataStore", "_ctx", "Context", "_echoNetworkAdapter", "EchoNetworkAdapter", "getContainingSpaceForDocument", "_getContainingSpaceForDocument", "bind", "_storage", "LevelDBStorageAdapter", "callbacks", "beforeSave", "params", "_beforeSave", "afterSave", "_afterSave", "_indexMetadataStore", "open", "_peerId", "PublicKey", "random", "toHex", "_clientNetwork", "LocalHostNetworkAdapter", "_repo", "Repo", "peerId", "sharePolicy", "_sharePolicy", "storage", "network", "ready", "whenConnected", "close", "dispose", "repo", "addReplicator", "replicator", "removeReplicator", "documentId", "startsWith", "peerMetadata", "peerMetadataByPeerId", "dxos_peerSource", "shouldAdvertize", "path", "batch", "handle", "handles", "doc", "docSync", "spaceKey", "getSpaceKeyFromDoc", "undefined", "lastAvailableHash", "getHeads", "objectIds", "Object", "keys", "objects", "encodedIds", "map", "objectId", "objectPointerCodec", "encode", "idToLastHash", "Map", "id", "markDirty", "notifyMarkedDirty", "_automergeDocs", "mapValues", "state", "hasDoc", "heads", "automerge", "data", "value", "key", "err", "_automergePeers", "peers", "spaceKeyHex", "from", "flush", "states", "Promise", "all", "invariant", "find", "waitForHeads", "syncRepo", "request", "sendSyncMessage", "getHostInfo", "trace", "info", "depth", "span", "showInBrowserTimeline", "resource", "rawSpaceKey", "access", "experimental_spaceKey", "String", "whenReady", "unavailableHeads", "Set", "Event", "wrap", "waitForCondition", "changeHash", "values", "changeIsPresentInDoc", "delete", "size", "getBackend", "getChangeByHash", "Event", "cancelWithContext", "warnAfterTimeout", "SpaceDocVersion", "invariant", "log", "trace", "AutomergeDocumentLoaderImpl", "constructor", "_spaceId", "_repo", "_spaceKey", "_spaceRootDocHandle", "_objectDocumentHandles", "Map", "_objectsPendingDocumentLoad", "Set", "onObjectDocumentLoaded", "getAllHandles", "values", "loadSpaceRootDocHandle", "ctx", "spaceState", "rootUrl", "error", "spaceId", "_createContextBoundSpaceRootDocument", "existingDocHandle", "_initDocHandle", "doc", "docSync", "access", "_initDocAccess", "loadObjectDocument", "objectIdOrMany", "objectIds", "Array", "isArray", "hasUrlsToLoad", "urlsToLoad", "objectId", "has", "spaceRootDoc", "documentUrl", "links", "add", "info", "_loadLinkedObjects", "onObjectLinksUpdated", "linksAwaitingLoad", "Object", "entries", "filter", "fromEntries", "forEach", "delete", "getSpaceRootDocHandle", "createDocumentForObject", "spaceDocHandle", "create", "version", "CURRENT", "onObjectBoundToDocument", "change", "newDoc", "url", "handle", "set", "clearHandleReferences", "objectsWithHandles", "keys", "clear", "automergeUrl", "logMeta", "objectDocumentHandle", "get", "warn", "actualDocumentUrl", "find", "debug", "_createObjectOnDocumentLoad", "docHandle", "whenReady", "err", "includes", "id", "documentId", "state", "Error", "onDispose", "spaceKey", "toHex", "docUrl", "listenerCount", "objectDocHandle", "emit", "shouldRetryLoading", "retryLoading", "span", "showInBrowserTimeline", "resource", "cbor", "Resource", "invariant", "PublicKey", "log", "AutomergeReplicator", "ComplexMap", "ComplexSet", "defaultMap", "MeshEchoReplicator", "_connections", "Set", "_connectionsPerPeer", "Map", "_authorizedDevices", "hash", "_context", "connect", "context", "disconnect", "connection", "close", "clear", "createExtension", "MeshReplicatorConnection", "ownPeerId", "peerId", "onRemoteConnected", "has", "onConnectionAuthScopeChanged", "set", "enable", "onConnectionOpen", "onRemoteDisconnected", "onConnectionClosed", "disable", "delete", "shouldAdvertize", "params", "documentId", "spaceKey", "getContainingSpaceForDocument", "authorizedDevices", "get", "remoteDeviceKey", "isAuthorized", "localPeer", "remotePeer", "deviceKey", "err", "catch", "add", "replicatorExtension", "authorizeDevice", "equals", "constructor", "_params", "_remotePeerId", "_isEnabled", "readableStreamController", "readable", "ReadableStream", "start", "controller", "_ctx", "onDispose", "writable", "WritableStream", "write", "message", "sendSyncMessage", "payload", "encode", "error", "onStartReplication", "info", "remotePeerId", "id", "thisPeerId", "toHex", "onSyncMessage", "decode", "enqueue", "onClose"]
7
7
  }