@dxos/echo-pipeline 0.5.3-main.37bbd91 → 0.5.3-main.3b535c7

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.
@@ -29,12 +29,12 @@ import { Event } from "@dxos/async";
29
29
  import { next as automerge, getBackend, getHeads } from "@dxos/automerge/automerge";
30
30
  import { Repo } from "@dxos/automerge/automerge-repo";
31
31
  import { Context } from "@dxos/context";
32
- import { invariant as invariant3 } from "@dxos/invariant";
32
+ import { invariant as invariant4 } from "@dxos/invariant";
33
33
  import { PublicKey } from "@dxos/keys";
34
- import { log as log3 } from "@dxos/log";
35
- import { objectPointerCodec } from "@dxos/protocols";
34
+ import { log as log4 } from "@dxos/log";
35
+ import { idCodec } from "@dxos/protocols";
36
36
  import { trace } from "@dxos/tracing";
37
- import { mapValues } from "@dxos/util";
37
+ import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
38
38
 
39
39
  // packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
40
40
  import { Trigger, synchronized } from "@dxos/async";
@@ -54,10 +54,12 @@ function _ts_decorate(decorators, target, key, desc) {
54
54
  }
55
55
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
56
56
  var EchoNetworkAdapter = class extends NetworkAdapter {
57
- constructor(_params) {
58
- super();
59
- this._params = _params;
57
+ constructor() {
58
+ super(...arguments);
60
59
  this._replicators = /* @__PURE__ */ new Set();
60
+ /**
61
+ * Remote peer id -> connection.
62
+ */
61
63
  this._connections = /* @__PURE__ */ new Map();
62
64
  this._lifecycleState = LifecycleState.CLOSED;
63
65
  this._connected = new Trigger();
@@ -76,7 +78,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
76
78
  if (connectionEntry.isOpen) {
77
79
  log.catch(err, void 0, {
78
80
  F: __dxlog_file,
79
- L: 49,
81
+ L: 40,
80
82
  S: this,
81
83
  C: (f, a) => f(...a)
82
84
  });
@@ -88,7 +90,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
88
90
  async open() {
89
91
  invariant(this._lifecycleState === LifecycleState.CLOSED, void 0, {
90
92
  F: __dxlog_file,
91
- L: 60,
93
+ L: 51,
92
94
  S: this,
93
95
  A: [
94
96
  "this._lifecycleState === LifecycleState.CLOSED",
@@ -96,12 +98,6 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
96
98
  ]
97
99
  });
98
100
  this._lifecycleState = LifecycleState.OPEN;
99
- log("emit ready", void 0, {
100
- F: __dxlog_file,
101
- L: 63,
102
- S: this,
103
- C: (f, a) => f(...a)
104
- });
105
101
  this.emit("ready", {
106
102
  network: this
107
103
  });
@@ -109,7 +105,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
109
105
  async close() {
110
106
  invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
111
107
  F: __dxlog_file,
112
- L: 71,
108
+ L: 61,
113
109
  S: this,
114
110
  A: [
115
111
  "this._lifecycleState === LifecycleState.OPEN",
@@ -128,18 +124,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
128
124
  });
129
125
  }
130
126
  async addReplicator(replicator) {
131
- invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
132
- F: __dxlog_file,
133
- L: 87,
134
- S: this,
135
- A: [
136
- "this._lifecycleState === LifecycleState.OPEN",
137
- ""
138
- ]
139
- });
140
127
  invariant(this.peerId, void 0, {
141
128
  F: __dxlog_file,
142
- L: 88,
129
+ L: 77,
143
130
  S: this,
144
131
  A: [
145
132
  "this.peerId",
@@ -148,43 +135,30 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
148
135
  });
149
136
  invariant(!this._replicators.has(replicator), void 0, {
150
137
  F: __dxlog_file,
151
- L: 89,
138
+ L: 78,
152
139
  S: this,
153
140
  A: [
154
141
  "!this._replicators.has(replicator)",
155
142
  ""
156
143
  ]
157
144
  });
158
- this._replicators.add(replicator);
159
145
  await replicator.connect({
160
146
  peerId: this.peerId,
161
147
  onConnectionOpen: this._onConnectionOpen.bind(this),
162
- onConnectionClosed: this._onConnectionClosed.bind(this),
163
- getContainingSpaceForDocument: this._params.getContainingSpaceForDocument
148
+ onConnectionClosed: this._onConnectionClosed.bind(this)
164
149
  });
165
150
  }
166
151
  async removeReplicator(replicator) {
167
- invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
168
- F: __dxlog_file,
169
- L: 102,
170
- S: this,
171
- A: [
172
- "this._lifecycleState === LifecycleState.OPEN",
173
- ""
174
- ]
175
- });
176
152
  invariant(this._replicators.has(replicator), void 0, {
177
153
  F: __dxlog_file,
178
- L: 103,
154
+ L: 89,
179
155
  S: this,
180
156
  A: [
181
157
  "this._replicators.has(replicator)",
182
158
  ""
183
159
  ]
184
160
  });
185
- "";
186
161
  await replicator.disconnect();
187
- this._replicators.delete(replicator);
188
162
  }
189
163
  async shouldAdvertize(peerId, params) {
190
164
  const connection = this._connections.get(peerId);
@@ -194,17 +168,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
194
168
  return connection.connection.shouldAdvertize(params);
195
169
  }
196
170
  _onConnectionOpen(connection) {
197
- log("Connection opened", {
198
- peerId: connection.peerId
199
- }, {
200
- F: __dxlog_file,
201
- L: 119,
202
- S: this,
203
- C: (f, a) => f(...a)
204
- });
205
171
  invariant(!this._connections.has(connection.peerId), void 0, {
206
172
  F: __dxlog_file,
207
- L: 120,
173
+ L: 103,
208
174
  S: this,
209
175
  A: [
210
176
  "!this._connections.has(connection.peerId as PeerId)",
@@ -233,21 +199,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
233
199
  if (connectionEntry.isOpen) {
234
200
  log.catch(err, void 0, {
235
201
  F: __dxlog_file,
236
- L: 139,
202
+ L: 122,
237
203
  S: this,
238
204
  C: (f, a) => f(...a)
239
205
  });
240
206
  }
241
207
  }
242
208
  });
243
- log("emit peer-candidate", {
244
- peerId: connection.peerId
245
- }, {
246
- F: __dxlog_file,
247
- L: 144,
248
- S: this,
249
- C: (f, a) => f(...a)
250
- });
251
209
  this.emit("peer-candidate", {
252
210
  peerId: connection.peerId,
253
211
  peerMetadata: {
@@ -257,18 +215,10 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
257
215
  });
258
216
  }
259
217
  _onConnectionClosed(connection) {
260
- log("Connection closed", {
261
- peerId: connection.peerId
262
- }, {
263
- F: __dxlog_file,
264
- L: 155,
265
- S: this,
266
- C: (f, a) => f(...a)
267
- });
268
218
  const entry = this._connections.get(connection.peerId);
269
219
  invariant(entry, void 0, {
270
220
  F: __dxlog_file,
271
- L: 157,
221
+ L: 138,
272
222
  S: this,
273
223
  A: [
274
224
  "entry",
@@ -281,13 +231,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
281
231
  });
282
232
  void entry.reader.cancel().catch((err) => log.catch(err, void 0, {
283
233
  F: __dxlog_file,
284
- L: 162,
234
+ L: 143,
285
235
  S: this,
286
236
  C: (f, a) => f(...a)
287
237
  }));
288
238
  void entry.writer.abort().catch((err) => log.catch(err, void 0, {
289
239
  F: __dxlog_file,
290
- L: 163,
240
+ L: 144,
291
241
  S: this,
292
242
  C: (f, a) => f(...a)
293
243
  }));
@@ -541,9 +491,126 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter2 {
541
491
  }
542
492
  };
543
493
 
494
+ // packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
495
+ import { Trigger as Trigger3 } from "@dxos/async";
496
+ import { NetworkAdapter as NetworkAdapter3, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
497
+ import { invariant as invariant3 } from "@dxos/invariant";
498
+ import { log as log2 } from "@dxos/log";
499
+ import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
500
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
501
+ var MeshNetworkAdapter = class extends NetworkAdapter3 {
502
+ constructor() {
503
+ super(...arguments);
504
+ this._extensions = /* @__PURE__ */ new Map();
505
+ this._connected = new Trigger3();
506
+ }
507
+ /**
508
+ * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
509
+ */
510
+ ready() {
511
+ this.emit("ready", {
512
+ network: this
513
+ });
514
+ }
515
+ connect(peerId) {
516
+ this.peerId = peerId;
517
+ this._connected.wake();
518
+ }
519
+ send(message) {
520
+ const receiverId = message.targetId;
521
+ const extension = this._extensions.get(receiverId);
522
+ invariant3(extension, "Extension not found.", {
523
+ F: __dxlog_file3,
524
+ L: 38,
525
+ S: this,
526
+ A: [
527
+ "extension",
528
+ "'Extension not found.'"
529
+ ]
530
+ });
531
+ extension.sendSyncMessage({
532
+ payload: cbor2.encode(message)
533
+ }).catch((err) => log2.catch(err, void 0, {
534
+ F: __dxlog_file3,
535
+ L: 39,
536
+ S: this,
537
+ C: (f, a) => f(...a)
538
+ }));
539
+ }
540
+ disconnect() {
541
+ }
542
+ createExtension() {
543
+ invariant3(this.peerId, "Peer id not set.", {
544
+ F: __dxlog_file3,
545
+ L: 47,
546
+ S: this,
547
+ A: [
548
+ "this.peerId",
549
+ "'Peer id not set.'"
550
+ ]
551
+ });
552
+ let peerInfo;
553
+ const extension = new AutomergeReplicator({
554
+ peerId: this.peerId
555
+ }, {
556
+ onStartReplication: async (info, remotePeerId) => {
557
+ await this._connected.wait();
558
+ log2("onStartReplication", {
559
+ id: info.id,
560
+ thisPeerId: this.peerId,
561
+ remotePeerId: remotePeerId.toHex()
562
+ }, {
563
+ F: __dxlog_file3,
564
+ L: 70,
565
+ S: this,
566
+ C: (f, a) => f(...a)
567
+ });
568
+ if (!this._extensions.has(info.id)) {
569
+ peerInfo = info;
570
+ this._extensions.set(info.id, extension);
571
+ log2("peer-candidate", {
572
+ id: info.id,
573
+ thisPeerId: this.peerId,
574
+ remotePeerId: remotePeerId.toHex()
575
+ }, {
576
+ F: __dxlog_file3,
577
+ L: 76,
578
+ S: this,
579
+ C: (f, a) => f(...a)
580
+ });
581
+ this.emit("peer-candidate", {
582
+ // TODO(mykola): Hack, stop abusing `peerMetadata` field.
583
+ peerMetadata: {
584
+ dxos_deviceKey: remotePeerId.toHex()
585
+ },
586
+ peerId: info.id
587
+ });
588
+ }
589
+ },
590
+ onSyncMessage: async ({ payload }) => {
591
+ if (!peerInfo) {
592
+ return;
593
+ }
594
+ const message = cbor2.decode(payload);
595
+ this.emit("message", message);
596
+ },
597
+ onClose: async () => {
598
+ if (!peerInfo) {
599
+ return;
600
+ }
601
+ this.emit("peer-disconnected", {
602
+ peerId: peerInfo.id
603
+ });
604
+ this._extensions.delete(peerInfo.id);
605
+ }
606
+ });
607
+ return extension;
608
+ }
609
+ };
610
+
544
611
  // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
545
612
  import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
546
- import { log as log2 } from "@dxos/log";
613
+ import { log as log3 } from "@dxos/log";
547
614
  import { StorageType } from "@dxos/random-access-storage";
548
615
 
549
616
  // packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
@@ -623,7 +690,7 @@ var AutomergeStorageAdapter = class {
623
690
  };
624
691
 
625
692
  // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
626
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
693
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
627
694
  var levelMigration = async ({ db, directory }) => {
628
695
  const isNewLevel = !await db.iterator({
629
696
  ...encodingOptions
@@ -637,10 +704,10 @@ var levelMigration = async ({ db, directory }) => {
637
704
  return;
638
705
  }
639
706
  const batch = db.batch();
640
- log2.info("found chunks on old storage adapter", {
707
+ log3.info("found chunks on old storage adapter", {
641
708
  chunks: chunks.length
642
709
  }, {
643
- F: __dxlog_file3,
710
+ F: __dxlog_file4,
644
711
  L: 36,
645
712
  S: void 0,
646
713
  C: (f, a) => f(...a)
@@ -664,13 +731,15 @@ function _ts_decorate2(decorators, target, key, desc) {
664
731
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
665
732
  return c > 3 && r && Object.defineProperty(target, key, r), r;
666
733
  }
667
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
734
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
668
735
  var AutomergeHost = class {
669
736
  constructor({ directory, db, indexMetadataStore }) {
670
737
  this._ctx = new Context();
671
- this._echoNetworkAdapter = new EchoNetworkAdapter({
672
- getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this)
673
- });
738
+ this._echoNetworkAdapter = new EchoNetworkAdapter();
739
+ /**
740
+ * spaceKey -> deviceKey[]
741
+ */
742
+ this._authorizedDevices = new ComplexMap(PublicKey.hash);
674
743
  this._requestedDocs = /* @__PURE__ */ new Set();
675
744
  this._directory = directory;
676
745
  this._db = db;
@@ -690,17 +759,103 @@ var AutomergeHost = class {
690
759
  });
691
760
  await this._storage.open?.();
692
761
  this._peerId = `host-${PublicKey.random().toHex()}`;
762
+ this._meshNetwork = new MeshNetworkAdapter();
693
763
  this._clientNetwork = new LocalHostNetworkAdapter();
694
764
  this._repo = new Repo({
695
765
  peerId: this._peerId,
696
766
  network: [
697
767
  this._clientNetwork,
768
+ this._meshNetwork,
698
769
  this._echoNetworkAdapter
699
770
  ],
700
771
  storage: this._storage,
701
- sharePolicy: this._sharePolicy.bind(this)
772
+ // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
773
+ // Hosts, running in the worker, don't share documents unless requested by other peers.
774
+ sharePolicy: async (peerId, documentId) => {
775
+ if (peerId.startsWith("client-")) {
776
+ return false;
777
+ }
778
+ if (!documentId) {
779
+ return false;
780
+ }
781
+ const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
782
+ if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
783
+ return this._echoNetworkAdapter.shouldAdvertize(peerId, {
784
+ documentId
785
+ });
786
+ }
787
+ const doc = this._repo.handles[documentId]?.docSync();
788
+ if (!doc) {
789
+ const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
790
+ log4("doc share policy check", {
791
+ peerId,
792
+ documentId,
793
+ isRequested
794
+ }, {
795
+ F: __dxlog_file5,
796
+ L: 124,
797
+ S: this,
798
+ C: (f, a) => f(...a)
799
+ });
800
+ return isRequested;
801
+ }
802
+ try {
803
+ const spaceKey = getSpaceKeyFromDoc(doc);
804
+ if (!spaceKey) {
805
+ log4("space key not found for share policy check", {
806
+ peerId,
807
+ documentId
808
+ }, {
809
+ F: __dxlog_file5,
810
+ L: 131,
811
+ S: this,
812
+ C: (f, a) => f(...a)
813
+ });
814
+ return false;
815
+ }
816
+ const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
817
+ const deviceKeyHex = peerMetadata?.dxos_deviceKey;
818
+ if (!deviceKeyHex) {
819
+ log4("device key not found for share policy check", {
820
+ peerId,
821
+ documentId
822
+ }, {
823
+ F: __dxlog_file5,
824
+ L: 140,
825
+ S: this,
826
+ C: (f, a) => f(...a)
827
+ });
828
+ return false;
829
+ }
830
+ const deviceKey = PublicKey.from(deviceKeyHex);
831
+ const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
832
+ log4("share policy check", {
833
+ localPeer: this._peerId,
834
+ remotePeer: peerId,
835
+ documentId,
836
+ deviceKey,
837
+ spaceKey,
838
+ isAuthorized
839
+ }, {
840
+ F: __dxlog_file5,
841
+ L: 146,
842
+ S: this,
843
+ C: (f, a) => f(...a)
844
+ });
845
+ return isAuthorized;
846
+ } catch (err) {
847
+ log4.catch(err, void 0, {
848
+ F: __dxlog_file5,
849
+ L: 156,
850
+ S: this,
851
+ C: (f, a) => f(...a)
852
+ });
853
+ return false;
854
+ }
855
+ }
702
856
  });
703
857
  this._clientNetwork.ready();
858
+ this._meshNetwork.ready();
704
859
  await this._echoNetworkAdapter.open();
705
860
  await this._clientNetwork.whenConnected();
706
861
  await this._echoNetworkAdapter.whenConnected();
@@ -720,40 +875,6 @@ var AutomergeHost = class {
720
875
  async removeReplicator(replicator) {
721
876
  await this._echoNetworkAdapter.removeReplicator(replicator);
722
877
  }
723
- // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
724
- // Hosts, running in the worker, don't share documents unless requested by other peers.
725
- // NOTE: If both peers return sharePolicy=false the replication will not happen
726
- // https://github.com/automerge/automerge-repo/pull/292
727
- async _sharePolicy(peerId, documentId) {
728
- if (peerId.startsWith("client-")) {
729
- return false;
730
- }
731
- if (!documentId) {
732
- return false;
733
- }
734
- const doc = this._repo.handles[documentId]?.docSync();
735
- if (!doc) {
736
- const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
737
- log3("doc share policy check", {
738
- peerId,
739
- documentId,
740
- isRequested
741
- }, {
742
- F: __dxlog_file4,
743
- L: 149,
744
- S: this,
745
- C: (f, a) => f(...a)
746
- });
747
- return isRequested;
748
- }
749
- const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
750
- if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
751
- return this._echoNetworkAdapter.shouldAdvertize(peerId, {
752
- documentId
753
- });
754
- }
755
- return false;
756
- }
757
878
  async _beforeSave({ path, batch }) {
758
879
  const handle = this._repo.handles[path[0]];
759
880
  if (!handle) {
@@ -763,13 +884,11 @@ var AutomergeHost = class {
763
884
  if (!doc) {
764
885
  return;
765
886
  }
766
- const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
767
887
  const lastAvailableHash = getHeads(doc);
768
888
  const objectIds = Object.keys(doc.objects ?? {});
769
- const encodedIds = objectIds.map((objectId) => objectPointerCodec.encode({
889
+ const encodedIds = objectIds.map((objectId) => idCodec.encode({
770
890
  documentId: handle.documentId,
771
- objectId,
772
- spaceKey
891
+ objectId
773
892
  }));
774
893
  const idToLastHash = new Map(encodedIds.map((id) => [
775
894
  id,
@@ -808,25 +927,14 @@ var AutomergeHost = class {
808
927
  _automergePeers() {
809
928
  return this._repo.peers;
810
929
  }
811
- async _getContainingSpaceForDocument(documentId) {
812
- const doc = this._repo.handles[documentId]?.docSync();
813
- if (!doc) {
814
- return null;
815
- }
816
- const spaceKeyHex = getSpaceKeyFromDoc(doc);
817
- if (!spaceKeyHex) {
818
- return null;
819
- }
820
- return PublicKey.from(spaceKeyHex);
821
- }
822
930
  //
823
931
  // Methods for client-services.
824
932
  //
825
933
  async flush({ states }) {
826
934
  await Promise.all(states?.map(async ({ heads, documentId }) => {
827
- invariant3(heads, "heads are required for flush", {
828
- F: __dxlog_file4,
829
- L: 243,
935
+ invariant4(heads, "heads are required for flush", {
936
+ F: __dxlog_file5,
937
+ L: 252,
830
938
  S: this,
831
939
  A: [
832
940
  "heads",
@@ -847,6 +955,24 @@ var AutomergeHost = class {
847
955
  async getHostInfo() {
848
956
  return this._clientNetwork.getHostInfo();
849
957
  }
958
+ //
959
+ // Mesh replication.
960
+ //
961
+ createExtension() {
962
+ return this._meshNetwork.createExtension();
963
+ }
964
+ authorizeDevice(spaceKey, deviceKey) {
965
+ log4("authorizeDevice", {
966
+ spaceKey,
967
+ deviceKey
968
+ }, {
969
+ F: __dxlog_file5,
970
+ L: 282,
971
+ S: this,
972
+ C: (f, a) => f(...a)
973
+ });
974
+ defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);
975
+ }
850
976
  };
851
977
  _ts_decorate2([
852
978
  trace.info()
@@ -899,8 +1025,8 @@ var changeIsPresentInDoc = (doc, changeHash) => {
899
1025
  import { Event as Event2 } from "@dxos/async";
900
1026
  import { cancelWithContext } from "@dxos/context";
901
1027
  import { warnAfterTimeout } from "@dxos/debug";
902
- import { invariant as invariant4 } from "@dxos/invariant";
903
- import { log as log4 } from "@dxos/log";
1028
+ import { invariant as invariant5 } from "@dxos/invariant";
1029
+ import { log as log5 } from "@dxos/log";
904
1030
  import { trace as trace2 } from "@dxos/tracing";
905
1031
  function _ts_decorate3(decorators, target, key, desc) {
906
1032
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -912,7 +1038,7 @@ function _ts_decorate3(decorators, target, key, desc) {
912
1038
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
913
1039
  return c > 3 && r && Object.defineProperty(target, key, r), r;
914
1040
  }
915
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
1041
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
916
1042
  var AutomergeDocumentLoaderImpl = class {
917
1043
  constructor(_spaceKey, _repo) {
918
1044
  this._spaceKey = _spaceKey;
@@ -933,10 +1059,10 @@ var AutomergeDocumentLoaderImpl = class {
933
1059
  return;
934
1060
  }
935
1061
  if (!spaceState.rootUrl) {
936
- log4.error("Database opened with no rootUrl", {
1062
+ log5.error("Database opened with no rootUrl", {
937
1063
  spaceKey: this._spaceKey
938
1064
  }, {
939
- F: __dxlog_file5,
1065
+ F: __dxlog_file6,
940
1066
  L: 70,
941
1067
  S: this,
942
1068
  C: (f, a) => f(...a)
@@ -945,8 +1071,8 @@ var AutomergeDocumentLoaderImpl = class {
945
1071
  } else {
946
1072
  const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
947
1073
  const doc = existingDocHandle.docSync();
948
- invariant4(doc, void 0, {
949
- F: __dxlog_file5,
1074
+ invariant5(doc, void 0, {
1075
+ F: __dxlog_file6,
950
1076
  L: 75,
951
1077
  S: this,
952
1078
  A: [
@@ -967,8 +1093,8 @@ var AutomergeDocumentLoaderImpl = class {
967
1093
  let hasUrlsToLoad = false;
968
1094
  const urlsToLoad = {};
969
1095
  for (const objectId of objectIds) {
970
- invariant4(this._spaceRootDocHandle, void 0, {
971
- F: __dxlog_file5,
1096
+ invariant5(this._spaceRootDocHandle, void 0, {
1097
+ F: __dxlog_file6,
972
1098
  L: 88,
973
1099
  S: this,
974
1100
  A: [
@@ -980,8 +1106,8 @@ var AutomergeDocumentLoaderImpl = class {
980
1106
  continue;
981
1107
  }
982
1108
  const spaceRootDoc = this._spaceRootDocHandle.docSync();
983
- invariant4(spaceRootDoc, void 0, {
984
- F: __dxlog_file5,
1109
+ invariant5(spaceRootDoc, void 0, {
1110
+ F: __dxlog_file6,
985
1111
  L: 93,
986
1112
  S: this,
987
1113
  A: [
@@ -992,10 +1118,10 @@ var AutomergeDocumentLoaderImpl = class {
992
1118
  const documentUrl = (spaceRootDoc.links ?? {})[objectId];
993
1119
  if (documentUrl == null) {
994
1120
  this._objectsPendingDocumentLoad.add(objectId);
995
- log4.info("loading delayed until object links are initialized", {
1121
+ log5.info("loading delayed until object links are initialized", {
996
1122
  objectId
997
1123
  }, {
998
- F: __dxlog_file5,
1124
+ F: __dxlog_file6,
999
1125
  L: 97,
1000
1126
  S: this,
1001
1127
  C: (f, a) => f(...a)
@@ -1018,8 +1144,8 @@ var AutomergeDocumentLoaderImpl = class {
1018
1144
  linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
1019
1145
  }
1020
1146
  getSpaceRootDocHandle() {
1021
- invariant4(this._spaceRootDocHandle, void 0, {
1022
- F: __dxlog_file5,
1147
+ invariant5(this._spaceRootDocHandle, void 0, {
1148
+ F: __dxlog_file6,
1023
1149
  L: 120,
1024
1150
  S: this,
1025
1151
  A: [
@@ -1030,8 +1156,8 @@ var AutomergeDocumentLoaderImpl = class {
1030
1156
  return this._spaceRootDocHandle;
1031
1157
  }
1032
1158
  createDocumentForObject(objectId) {
1033
- invariant4(this._spaceRootDocHandle, void 0, {
1034
- F: __dxlog_file5,
1159
+ invariant5(this._spaceRootDocHandle, void 0, {
1160
+ F: __dxlog_file6,
1035
1161
  L: 125,
1036
1162
  S: this,
1037
1163
  A: [
@@ -1070,11 +1196,11 @@ var AutomergeDocumentLoaderImpl = class {
1070
1196
  };
1071
1197
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
1072
1198
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
1073
- log4.warn("object already inlined in a different document, ignoring the link", {
1199
+ log5.warn("object already inlined in a different document, ignoring the link", {
1074
1200
  ...logMeta,
1075
1201
  actualDocumentUrl: objectDocumentHandle.url
1076
1202
  }, {
1077
- F: __dxlog_file5,
1203
+ F: __dxlog_file6,
1078
1204
  L: 155,
1079
1205
  S: this,
1080
1206
  C: (f, a) => f(...a)
@@ -1082,8 +1208,8 @@ var AutomergeDocumentLoaderImpl = class {
1082
1208
  continue;
1083
1209
  }
1084
1210
  if (objectDocumentHandle?.url === automergeUrl) {
1085
- log4.warn("object document was already loaded", logMeta, {
1086
- F: __dxlog_file5,
1211
+ log5.warn("object document was already loaded", logMeta, {
1212
+ F: __dxlog_file6,
1087
1213
  L: 162,
1088
1214
  S: this,
1089
1215
  C: (f, a) => f(...a)
@@ -1091,8 +1217,8 @@ var AutomergeDocumentLoaderImpl = class {
1091
1217
  continue;
1092
1218
  }
1093
1219
  const handle = this._repo.find(automergeUrl);
1094
- log4.debug("document loading triggered", logMeta, {
1095
- F: __dxlog_file5,
1220
+ log5.debug("document loading triggered", logMeta, {
1221
+ F: __dxlog_file6,
1096
1222
  L: 166,
1097
1223
  S: this,
1098
1224
  C: (f, a) => f(...a)
@@ -1111,11 +1237,11 @@ var AutomergeDocumentLoaderImpl = class {
1111
1237
  break;
1112
1238
  } catch (err) {
1113
1239
  if (`${err}`.includes("Timeout")) {
1114
- log4.info("wraparound", {
1240
+ log5.info("wraparound", {
1115
1241
  id: docHandle.documentId,
1116
1242
  state: docHandle.state
1117
1243
  }, {
1118
- F: __dxlog_file5,
1244
+ F: __dxlog_file6,
1119
1245
  L: 182,
1120
1246
  S: this,
1121
1247
  C: (f, a) => f(...a)
@@ -1156,8 +1282,8 @@ var AutomergeDocumentLoaderImpl = class {
1156
1282
  docUrl: handle.url
1157
1283
  };
1158
1284
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
1159
- log4.info("document loaded after all listeners were removed", logMeta, {
1160
- F: __dxlog_file5,
1285
+ log5.info("document loaded after all listeners were removed", logMeta, {
1286
+ F: __dxlog_file6,
1161
1287
  L: 218,
1162
1288
  S: this,
1163
1289
  C: (f, a) => f(...a)
@@ -1166,8 +1292,8 @@ var AutomergeDocumentLoaderImpl = class {
1166
1292
  }
1167
1293
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
1168
1294
  if (objectDocHandle?.url !== handle.url) {
1169
- log4.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1170
- F: __dxlog_file5,
1295
+ log5.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1296
+ F: __dxlog_file6,
1171
1297
  L: 223,
1172
1298
  S: this,
1173
1299
  C: (f, a) => f(...a)
@@ -1180,13 +1306,13 @@ var AutomergeDocumentLoaderImpl = class {
1180
1306
  });
1181
1307
  } catch (err) {
1182
1308
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1183
- log4.warn("failed to load a document", {
1309
+ log5.warn("failed to load a document", {
1184
1310
  objectId,
1185
1311
  automergeUrl: handle.url,
1186
1312
  retryLoading: shouldRetryLoading,
1187
1313
  err
1188
1314
  }, {
1189
- F: __dxlog_file5,
1315
+ F: __dxlog_file6,
1190
1316
  L: 229,
1191
1317
  S: this,
1192
1318
  C: (f, a) => f(...a)
@@ -1205,272 +1331,6 @@ _ts_decorate3([
1205
1331
  AutomergeDocumentLoaderImpl = _ts_decorate3([
1206
1332
  trace2.resource()
1207
1333
  ], AutomergeDocumentLoaderImpl);
1208
-
1209
- // packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
1210
- import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
1211
- import { Resource as Resource2 } from "@dxos/context";
1212
- import { invariant as invariant5 } from "@dxos/invariant";
1213
- import { PublicKey as PublicKey2 } from "@dxos/keys";
1214
- import { log as log5 } from "@dxos/log";
1215
- import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
1216
- import { ComplexMap, ComplexSet, defaultMap } from "@dxos/util";
1217
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
1218
- var MeshEchoReplicator = class {
1219
- constructor() {
1220
- this._connections = /* @__PURE__ */ new Set();
1221
- /**
1222
- * Using automerge peerId as a key.
1223
- */
1224
- this._connectionsPerPeer = /* @__PURE__ */ new Map();
1225
- /**
1226
- * spaceKey -> deviceKey[]
1227
- */
1228
- this._authorizedDevices = new ComplexMap(PublicKey2.hash);
1229
- this._context = null;
1230
- }
1231
- async connect(context) {
1232
- this._context = context;
1233
- }
1234
- async disconnect() {
1235
- for (const connection of this._connections) {
1236
- await connection.close();
1237
- }
1238
- this._connections.clear();
1239
- this._connectionsPerPeer.clear();
1240
- this._context = null;
1241
- }
1242
- createExtension() {
1243
- invariant5(this._context, void 0, {
1244
- F: __dxlog_file6,
1245
- L: 54,
1246
- S: this,
1247
- A: [
1248
- "this._context",
1249
- ""
1250
- ]
1251
- });
1252
- const connection = new MeshReplicatorConnection({
1253
- ownPeerId: this._context.peerId,
1254
- onRemoteConnected: async () => {
1255
- log5("onRemoteConnected", {
1256
- peerId: connection.peerId
1257
- }, {
1258
- F: __dxlog_file6,
1259
- L: 59,
1260
- S: this,
1261
- C: (f, a) => f(...a)
1262
- });
1263
- invariant5(this._context, void 0, {
1264
- F: __dxlog_file6,
1265
- L: 60,
1266
- S: this,
1267
- A: [
1268
- "this._context",
1269
- ""
1270
- ]
1271
- });
1272
- if (!this._connectionsPerPeer.has(connection.peerId)) {
1273
- this._connectionsPerPeer.set(connection.peerId, connection);
1274
- await connection.enable();
1275
- this._context.onConnectionOpen(connection);
1276
- }
1277
- },
1278
- onRemoteDisconnected: async () => {
1279
- log5("onRemoteDisconnected", {
1280
- peerId: connection.peerId
1281
- }, {
1282
- F: __dxlog_file6,
1283
- L: 69,
1284
- S: this,
1285
- C: (f, a) => f(...a)
1286
- });
1287
- this._context?.onConnectionClosed(connection);
1288
- await connection.disable();
1289
- this._connectionsPerPeer.delete(connection.peerId);
1290
- this._connections.delete(connection);
1291
- },
1292
- shouldAdvertize: async (params) => {
1293
- log5("shouldAdvertize", {
1294
- peerId: connection.peerId,
1295
- documentId: params.documentId
1296
- }, {
1297
- F: __dxlog_file6,
1298
- L: 76,
1299
- S: this,
1300
- C: (f, a) => f(...a)
1301
- });
1302
- invariant5(this._context, void 0, {
1303
- F: __dxlog_file6,
1304
- L: 77,
1305
- S: this,
1306
- A: [
1307
- "this._context",
1308
- ""
1309
- ]
1310
- });
1311
- try {
1312
- const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
1313
- if (!spaceKey) {
1314
- log5("space key not found for share policy check", {
1315
- peerId: connection.peerId,
1316
- documentId: params.documentId
1317
- }, {
1318
- F: __dxlog_file6,
1319
- L: 81,
1320
- S: this,
1321
- C: (f, a) => f(...a)
1322
- });
1323
- return false;
1324
- }
1325
- const authorizedDevices = this._authorizedDevices.get(spaceKey);
1326
- if (!connection.remoteDeviceKey) {
1327
- log5("device key not found for share policy check", {
1328
- peerId: connection.peerId,
1329
- documentId: params.documentId
1330
- }, {
1331
- F: __dxlog_file6,
1332
- L: 91,
1333
- S: this,
1334
- C: (f, a) => f(...a)
1335
- });
1336
- return false;
1337
- }
1338
- const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
1339
- log5("share policy check", {
1340
- localPeer: this._context.peerId,
1341
- remotePeer: connection.peerId,
1342
- documentId: params.documentId,
1343
- deviceKey: connection.remoteDeviceKey,
1344
- spaceKey,
1345
- isAuthorized
1346
- }, {
1347
- F: __dxlog_file6,
1348
- L: 99,
1349
- S: this,
1350
- C: (f, a) => f(...a)
1351
- });
1352
- return isAuthorized;
1353
- } catch (err) {
1354
- log5.catch(err, void 0, {
1355
- F: __dxlog_file6,
1356
- L: 109,
1357
- S: this,
1358
- C: (f, a) => f(...a)
1359
- });
1360
- return false;
1361
- }
1362
- }
1363
- });
1364
- this._connections.add(connection);
1365
- return connection.replicatorExtension;
1366
- }
1367
- authorizeDevice(spaceKey, deviceKey) {
1368
- log5("authorizeDevice", {
1369
- spaceKey,
1370
- deviceKey
1371
- }, {
1372
- F: __dxlog_file6,
1373
- L: 120,
1374
- S: this,
1375
- C: (f, a) => f(...a)
1376
- });
1377
- defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey2.hash)).add(deviceKey);
1378
- }
1379
- };
1380
- var MeshReplicatorConnection = class extends Resource2 {
1381
- constructor(_params) {
1382
- super();
1383
- this._params = _params;
1384
- this.remoteDeviceKey = null;
1385
- this._remotePeerId = null;
1386
- this._isEnabled = false;
1387
- let readableStreamController;
1388
- this.readable = new ReadableStream({
1389
- start: (controller) => {
1390
- readableStreamController = controller;
1391
- this._ctx.onDispose(() => controller.close());
1392
- }
1393
- });
1394
- this.writable = new WritableStream({
1395
- write: async (message, controller) => {
1396
- this.replicatorExtension.sendSyncMessage({
1397
- payload: cbor2.encode(message)
1398
- }).catch((err) => {
1399
- controller.error(err);
1400
- });
1401
- }
1402
- });
1403
- this.replicatorExtension = new AutomergeReplicator({
1404
- peerId: this._params.ownPeerId
1405
- }, {
1406
- onStartReplication: async (info, remotePeerId) => {
1407
- this.remoteDeviceKey = remotePeerId;
1408
- this._remotePeerId = info.id;
1409
- log5("onStartReplication", {
1410
- id: info.id,
1411
- thisPeerId: this.peerId,
1412
- remotePeerId: remotePeerId.toHex()
1413
- }, {
1414
- F: __dxlog_file6,
1415
- L: 185,
1416
- S: this,
1417
- C: (f, a) => f(...a)
1418
- });
1419
- await this._params.onRemoteConnected();
1420
- },
1421
- onSyncMessage: async ({ payload }) => {
1422
- if (!this._isEnabled) {
1423
- return;
1424
- }
1425
- const message = cbor2.decode(payload);
1426
- readableStreamController.enqueue(message);
1427
- },
1428
- onClose: async () => {
1429
- if (!this._isEnabled) {
1430
- return;
1431
- }
1432
- await this._params.onRemoteDisconnected();
1433
- }
1434
- });
1435
- }
1436
- get peerId() {
1437
- invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1438
- F: __dxlog_file6,
1439
- L: 208,
1440
- S: this,
1441
- A: [
1442
- "this._remotePeerId != null",
1443
- "'Remote peer has not connected yet.'"
1444
- ]
1445
- });
1446
- return this._remotePeerId;
1447
- }
1448
- async shouldAdvertize(params) {
1449
- return this._params.shouldAdvertize(params);
1450
- }
1451
- /**
1452
- * Start exchanging messages with the remote peer.
1453
- * Call after the remote peer has connected.
1454
- */
1455
- async enable() {
1456
- invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1457
- F: __dxlog_file6,
1458
- L: 221,
1459
- S: this,
1460
- A: [
1461
- "this._remotePeerId != null",
1462
- "'Remote peer has not connected yet.'"
1463
- ]
1464
- });
1465
- this._isEnabled = true;
1466
- }
1467
- /**
1468
- * Stop exchanging messages with the remote peer.
1469
- */
1470
- async disable() {
1471
- this._isEnabled = false;
1472
- }
1473
- };
1474
1334
  export {
1475
1335
  AuthExtension,
1476
1336
  AuthStatus,
@@ -1482,7 +1342,7 @@ export {
1482
1342
  LocalHostNetworkAdapter,
1483
1343
  MOCK_AUTH_PROVIDER,
1484
1344
  MOCK_AUTH_VERIFIER,
1485
- MeshEchoReplicator,
1345
+ MeshNetworkAdapter,
1486
1346
  MetadataStore,
1487
1347
  Pipeline,
1488
1348
  SnapshotManager,