@dxos/echo-pipeline 0.5.1-next.260c093 → 0.5.1-next.26de2f3

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,15 +29,236 @@ 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";
34
+ import { log as log4 } from "@dxos/log";
35
35
  import { idCodec } from "@dxos/protocols";
36
36
  import { trace } from "@dxos/tracing";
37
37
  import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
38
38
 
39
+ // packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
40
+ import { Trigger, synchronized } from "@dxos/async";
41
+ import { NetworkAdapter } from "@dxos/automerge/automerge-repo";
42
+ import { LifecycleState } from "@dxos/context";
43
+ import { invariant } from "@dxos/invariant";
44
+ import { log } from "@dxos/log";
45
+ function _ts_decorate(decorators, target, key, desc) {
46
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
47
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
48
+ r = Reflect.decorate(decorators, target, key, desc);
49
+ else
50
+ for (var i = decorators.length - 1; i >= 0; i--)
51
+ if (d = decorators[i])
52
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
53
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
54
+ }
55
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
56
+ var EchoNetworkAdapter = class extends NetworkAdapter {
57
+ constructor() {
58
+ super(...arguments);
59
+ this._replicators = /* @__PURE__ */ new Set();
60
+ /**
61
+ * Remote peer id -> connection.
62
+ */
63
+ this._connections = /* @__PURE__ */ new Map();
64
+ this._lifecycleState = LifecycleState.CLOSED;
65
+ this._connected = new Trigger();
66
+ }
67
+ connect(peerId, peerMetadata) {
68
+ this.peerId = peerId;
69
+ this.peerMetadata = peerMetadata;
70
+ this._connected.wake();
71
+ }
72
+ send(message) {
73
+ const connectionEntry = this._connections.get(message.targetId);
74
+ if (!connectionEntry) {
75
+ throw new Error("Connection not found.");
76
+ }
77
+ connectionEntry.writer.write(message).catch((err) => {
78
+ if (connectionEntry.isOpen) {
79
+ log.catch(err, void 0, {
80
+ F: __dxlog_file,
81
+ L: 40,
82
+ S: this,
83
+ C: (f, a) => f(...a)
84
+ });
85
+ }
86
+ });
87
+ }
88
+ disconnect() {
89
+ }
90
+ async open() {
91
+ invariant(this._lifecycleState === LifecycleState.CLOSED, void 0, {
92
+ F: __dxlog_file,
93
+ L: 51,
94
+ S: this,
95
+ A: [
96
+ "this._lifecycleState === LifecycleState.CLOSED",
97
+ ""
98
+ ]
99
+ });
100
+ this._lifecycleState = LifecycleState.OPEN;
101
+ this.emit("ready", {
102
+ network: this
103
+ });
104
+ }
105
+ async close() {
106
+ invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
107
+ F: __dxlog_file,
108
+ L: 61,
109
+ S: this,
110
+ A: [
111
+ "this._lifecycleState === LifecycleState.OPEN",
112
+ ""
113
+ ]
114
+ });
115
+ for (const replicator of this._replicators) {
116
+ await replicator.disconnect();
117
+ }
118
+ this._replicators.clear();
119
+ this._lifecycleState = LifecycleState.CLOSED;
120
+ }
121
+ async whenConnected() {
122
+ await this._connected.wait({
123
+ timeout: 1e4
124
+ });
125
+ }
126
+ async addReplicator(replicator) {
127
+ invariant(this.peerId, void 0, {
128
+ F: __dxlog_file,
129
+ L: 77,
130
+ S: this,
131
+ A: [
132
+ "this.peerId",
133
+ ""
134
+ ]
135
+ });
136
+ invariant(!this._replicators.has(replicator), void 0, {
137
+ F: __dxlog_file,
138
+ L: 78,
139
+ S: this,
140
+ A: [
141
+ "!this._replicators.has(replicator)",
142
+ ""
143
+ ]
144
+ });
145
+ await replicator.connect({
146
+ peerId: this.peerId,
147
+ onConnectionOpen: this._onConnectionOpen.bind(this),
148
+ onConnectionClosed: this._onConnectionClosed.bind(this)
149
+ });
150
+ }
151
+ async removeReplicator(replicator) {
152
+ invariant(this._replicators.has(replicator), void 0, {
153
+ F: __dxlog_file,
154
+ L: 89,
155
+ S: this,
156
+ A: [
157
+ "this._replicators.has(replicator)",
158
+ ""
159
+ ]
160
+ });
161
+ await replicator.disconnect();
162
+ }
163
+ async shouldAdvertize(peerId, params) {
164
+ const connection = this._connections.get(peerId);
165
+ if (!connection) {
166
+ return false;
167
+ }
168
+ return connection.connection.shouldAdvertize(params);
169
+ }
170
+ _onConnectionOpen(connection) {
171
+ invariant(!this._connections.has(connection.peerId), void 0, {
172
+ F: __dxlog_file,
173
+ L: 103,
174
+ S: this,
175
+ A: [
176
+ "!this._connections.has(connection.peerId as PeerId)",
177
+ ""
178
+ ]
179
+ });
180
+ const reader = connection.readable.getReader();
181
+ const writer = connection.writable.getWriter();
182
+ const connectionEntry = {
183
+ connection,
184
+ reader,
185
+ writer,
186
+ isOpen: true
187
+ };
188
+ this._connections.set(connection.peerId, connectionEntry);
189
+ queueMicrotask(async () => {
190
+ try {
191
+ while (true) {
192
+ const { done, value } = await reader.read();
193
+ if (done) {
194
+ break;
195
+ }
196
+ this.emit("message", value);
197
+ }
198
+ } catch (err) {
199
+ if (connectionEntry.isOpen) {
200
+ log.catch(err, void 0, {
201
+ F: __dxlog_file,
202
+ L: 122,
203
+ S: this,
204
+ C: (f, a) => f(...a)
205
+ });
206
+ }
207
+ }
208
+ });
209
+ this.emit("peer-candidate", {
210
+ peerId: connection.peerId,
211
+ peerMetadata: {
212
+ // TODO(dmaretskyi): Refactor this.
213
+ dxos_peerSource: "EchoNetworkAdapter"
214
+ }
215
+ });
216
+ }
217
+ _onConnectionClosed(connection) {
218
+ const entry = this._connections.get(connection.peerId);
219
+ invariant(entry, void 0, {
220
+ F: __dxlog_file,
221
+ L: 138,
222
+ S: this,
223
+ A: [
224
+ "entry",
225
+ ""
226
+ ]
227
+ });
228
+ entry.isOpen = false;
229
+ this.emit("peer-disconnected", {
230
+ peerId: connection.peerId
231
+ });
232
+ void entry.reader.cancel().catch((err) => log.catch(err, void 0, {
233
+ F: __dxlog_file,
234
+ L: 143,
235
+ S: this,
236
+ C: (f, a) => f(...a)
237
+ }));
238
+ void entry.writer.abort().catch((err) => log.catch(err, void 0, {
239
+ F: __dxlog_file,
240
+ L: 144,
241
+ S: this,
242
+ C: (f, a) => f(...a)
243
+ }));
244
+ this._connections.delete(connection.peerId);
245
+ }
246
+ };
247
+ _ts_decorate([
248
+ synchronized
249
+ ], EchoNetworkAdapter.prototype, "open", null);
250
+ _ts_decorate([
251
+ synchronized
252
+ ], EchoNetworkAdapter.prototype, "close", null);
253
+ _ts_decorate([
254
+ synchronized
255
+ ], EchoNetworkAdapter.prototype, "addReplicator", null);
256
+ _ts_decorate([
257
+ synchronized
258
+ ], EchoNetworkAdapter.prototype, "removeReplicator", null);
259
+
39
260
  // packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
40
- import { LifecycleState, Resource } from "@dxos/context";
261
+ import { LifecycleState as LifecycleState2, Resource } from "@dxos/context";
41
262
  var LevelDBStorageAdapter = class extends Resource {
42
263
  constructor(_params) {
43
264
  super();
@@ -45,7 +266,7 @@ var LevelDBStorageAdapter = class extends Resource {
45
266
  }
46
267
  async load(keyArray) {
47
268
  try {
48
- if (this._lifecycleState !== LifecycleState.OPEN) {
269
+ if (this._lifecycleState !== LifecycleState2.OPEN) {
49
270
  return void 0;
50
271
  }
51
272
  return await this._params.db.get(keyArray, {
@@ -59,7 +280,7 @@ var LevelDBStorageAdapter = class extends Resource {
59
280
  }
60
281
  }
61
282
  async save(keyArray, binary) {
62
- if (this._lifecycleState !== LifecycleState.OPEN) {
283
+ if (this._lifecycleState !== LifecycleState2.OPEN) {
63
284
  return void 0;
64
285
  }
65
286
  const batch = this._params.db.batch();
@@ -74,7 +295,7 @@ var LevelDBStorageAdapter = class extends Resource {
74
295
  await this._params.callbacks?.afterSave?.(keyArray);
75
296
  }
76
297
  async remove(keyArray) {
77
- if (this._lifecycleState !== LifecycleState.OPEN) {
298
+ if (this._lifecycleState !== LifecycleState2.OPEN) {
78
299
  return void 0;
79
300
  }
80
301
  await this._params.db.del(keyArray, {
@@ -82,7 +303,7 @@ var LevelDBStorageAdapter = class extends Resource {
82
303
  });
83
304
  }
84
305
  async loadRange(keyPrefix) {
85
- if (this._lifecycleState !== LifecycleState.OPEN) {
306
+ if (this._lifecycleState !== LifecycleState2.OPEN) {
86
307
  return [];
87
308
  }
88
309
  const result = [];
@@ -102,7 +323,7 @@ var LevelDBStorageAdapter = class extends Resource {
102
323
  return result;
103
324
  }
104
325
  async removeRange(keyPrefix) {
105
- if (this._lifecycleState !== LifecycleState.OPEN) {
326
+ if (this._lifecycleState !== LifecycleState2.OPEN) {
106
327
  return void 0;
107
328
  }
108
329
  const batch = this._params.db.batch();
@@ -133,16 +354,16 @@ var encodingOptions = {
133
354
  var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
134
355
 
135
356
  // packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
136
- import { Trigger } from "@dxos/async";
137
- import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
357
+ import { Trigger as Trigger2 } from "@dxos/async";
358
+ import { NetworkAdapter as NetworkAdapter2, cbor } from "@dxos/automerge/automerge-repo";
138
359
  import { Stream } from "@dxos/codec-protobuf";
139
- import { invariant } from "@dxos/invariant";
140
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
141
- var LocalHostNetworkAdapter = class extends NetworkAdapter {
360
+ import { invariant as invariant2 } from "@dxos/invariant";
361
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
362
+ var LocalHostNetworkAdapter = class extends NetworkAdapter2 {
142
363
  constructor() {
143
364
  super(...arguments);
144
365
  this._peers = /* @__PURE__ */ new Map();
145
- this._connected = new Trigger();
366
+ this._connected = new Trigger2();
146
367
  this._isConnected = false;
147
368
  }
148
369
  /**
@@ -165,8 +386,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
165
386
  }
166
387
  send(message) {
167
388
  const peer = this._peers.get(message.targetId);
168
- invariant(peer, "Peer not found.", {
169
- F: __dxlog_file,
389
+ invariant2(peer, "Peer not found.", {
390
+ F: __dxlog_file2,
170
391
  L: 51,
171
392
  S: this,
172
393
  A: [
@@ -190,8 +411,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
190
411
  syncRepo({ id, syncMessage }) {
191
412
  const peerId = this._getPeerId(id);
192
413
  return new Stream(({ next, close }) => {
193
- invariant(!this._peers.has(peerId), "Peer already connected.", {
194
- F: __dxlog_file,
414
+ invariant2(!this._peers.has(peerId), "Peer already connected.", {
415
+ F: __dxlog_file2,
195
416
  L: 73,
196
417
  S: this,
197
418
  A: [
@@ -214,8 +435,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
214
435
  });
215
436
  }
216
437
  });
217
- invariant(this._isConnected, void 0, {
218
- F: __dxlog_file,
438
+ invariant2(this._isConnected, void 0, {
439
+ F: __dxlog_file2,
219
440
  L: 90,
220
441
  S: this,
221
442
  A: [
@@ -230,8 +451,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
230
451
  });
231
452
  }
232
453
  async sendSyncMessage({ id, syncMessage }) {
233
- invariant(this._isConnected, void 0, {
234
- F: __dxlog_file,
454
+ invariant2(this._isConnected, void 0, {
455
+ F: __dxlog_file2,
235
456
  L: 99,
236
457
  S: this,
237
458
  A: [
@@ -243,8 +464,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
243
464
  this.emit("message", message);
244
465
  }
245
466
  async getHostInfo() {
246
- invariant(this._isConnected, void 0, {
247
- F: __dxlog_file,
467
+ invariant2(this._isConnected, void 0, {
468
+ F: __dxlog_file2,
248
469
  L: 105,
249
470
  S: this,
250
471
  A: [
@@ -252,8 +473,8 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
252
473
  ""
253
474
  ]
254
475
  });
255
- invariant(this.peerId, "Peer id not set.", {
256
- F: __dxlog_file,
476
+ invariant2(this.peerId, "Peer id not set.", {
477
+ F: __dxlog_file2,
257
478
  L: 106,
258
479
  S: this,
259
480
  A: [
@@ -271,17 +492,17 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
271
492
  };
272
493
 
273
494
  // packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
274
- import { Trigger as Trigger2 } from "@dxos/async";
275
- import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
276
- import { invariant as invariant2 } from "@dxos/invariant";
277
- import { log } from "@dxos/log";
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";
278
499
  import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
279
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
280
- var MeshNetworkAdapter = class extends NetworkAdapter2 {
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 {
281
502
  constructor() {
282
503
  super(...arguments);
283
504
  this._extensions = /* @__PURE__ */ new Map();
284
- this._connected = new Trigger2();
505
+ this._connected = new Trigger3();
285
506
  }
286
507
  /**
287
508
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -298,8 +519,8 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
298
519
  send(message) {
299
520
  const receiverId = message.targetId;
300
521
  const extension = this._extensions.get(receiverId);
301
- invariant2(extension, "Extension not found.", {
302
- F: __dxlog_file2,
522
+ invariant3(extension, "Extension not found.", {
523
+ F: __dxlog_file3,
303
524
  L: 38,
304
525
  S: this,
305
526
  A: [
@@ -309,8 +530,8 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
309
530
  });
310
531
  extension.sendSyncMessage({
311
532
  payload: cbor2.encode(message)
312
- }).catch((err) => log.catch(err, void 0, {
313
- F: __dxlog_file2,
533
+ }).catch((err) => log2.catch(err, void 0, {
534
+ F: __dxlog_file3,
314
535
  L: 39,
315
536
  S: this,
316
537
  C: (f, a) => f(...a)
@@ -319,8 +540,8 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
319
540
  disconnect() {
320
541
  }
321
542
  createExtension() {
322
- invariant2(this.peerId, "Peer id not set.", {
323
- F: __dxlog_file2,
543
+ invariant3(this.peerId, "Peer id not set.", {
544
+ F: __dxlog_file3,
324
545
  L: 47,
325
546
  S: this,
326
547
  A: [
@@ -334,12 +555,12 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
334
555
  }, {
335
556
  onStartReplication: async (info, remotePeerId) => {
336
557
  await this._connected.wait();
337
- log("onStartReplication", {
558
+ log2("onStartReplication", {
338
559
  id: info.id,
339
560
  thisPeerId: this.peerId,
340
561
  remotePeerId: remotePeerId.toHex()
341
562
  }, {
342
- F: __dxlog_file2,
563
+ F: __dxlog_file3,
343
564
  L: 70,
344
565
  S: this,
345
566
  C: (f, a) => f(...a)
@@ -347,12 +568,12 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
347
568
  if (!this._extensions.has(info.id)) {
348
569
  peerInfo = info;
349
570
  this._extensions.set(info.id, extension);
350
- log("peer-candidate", {
571
+ log2("peer-candidate", {
351
572
  id: info.id,
352
573
  thisPeerId: this.peerId,
353
574
  remotePeerId: remotePeerId.toHex()
354
575
  }, {
355
- F: __dxlog_file2,
576
+ F: __dxlog_file3,
356
577
  L: 76,
357
578
  S: this,
358
579
  C: (f, a) => f(...a)
@@ -389,7 +610,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
389
610
 
390
611
  // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
391
612
  import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
392
- import { log as log2 } from "@dxos/log";
613
+ import { log as log3 } from "@dxos/log";
393
614
  import { StorageType } from "@dxos/random-access-storage";
394
615
 
395
616
  // packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
@@ -469,7 +690,7 @@ var AutomergeStorageAdapter = class {
469
690
  };
470
691
 
471
692
  // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
472
- 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";
473
694
  var levelMigration = async ({ db, directory }) => {
474
695
  const isNewLevel = !await db.iterator({
475
696
  ...encodingOptions
@@ -483,10 +704,10 @@ var levelMigration = async ({ db, directory }) => {
483
704
  return;
484
705
  }
485
706
  const batch = db.batch();
486
- log2.info("found chunks on old storage adapter", {
707
+ log3.info("found chunks on old storage adapter", {
487
708
  chunks: chunks.length
488
709
  }, {
489
- F: __dxlog_file3,
710
+ F: __dxlog_file4,
490
711
  L: 36,
491
712
  S: void 0,
492
713
  C: (f, a) => f(...a)
@@ -500,7 +721,7 @@ var levelMigration = async ({ db, directory }) => {
500
721
  };
501
722
 
502
723
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
503
- function _ts_decorate(decorators, target, key, desc) {
724
+ function _ts_decorate2(decorators, target, key, desc) {
504
725
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
505
726
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
506
727
  r = Reflect.decorate(decorators, target, key, desc);
@@ -510,10 +731,11 @@ function _ts_decorate(decorators, target, key, desc) {
510
731
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
511
732
  return c > 3 && r && Object.defineProperty(target, key, r), r;
512
733
  }
513
- 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";
514
735
  var AutomergeHost = class {
515
736
  constructor({ directory, db, indexMetadataStore }) {
516
737
  this._ctx = new Context();
738
+ this._echoNetworkAdapter = new EchoNetworkAdapter();
517
739
  /**
518
740
  * spaceKey -> deviceKey[]
519
741
  */
@@ -543,7 +765,8 @@ var AutomergeHost = class {
543
765
  peerId: this._peerId,
544
766
  network: [
545
767
  this._clientNetwork,
546
- this._meshNetwork
768
+ this._meshNetwork,
769
+ this._echoNetworkAdapter
547
770
  ],
548
771
  storage: this._storage,
549
772
  // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
@@ -555,16 +778,22 @@ var AutomergeHost = class {
555
778
  if (!documentId) {
556
779
  return false;
557
780
  }
781
+ const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
782
+ if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
783
+ return this._echoNetworkAdapter.shouldAdvertize(peerId, {
784
+ documentId
785
+ });
786
+ }
558
787
  const doc = this._repo.handles[documentId]?.docSync();
559
788
  if (!doc) {
560
789
  const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
561
- log3("doc share policy check", {
790
+ log4("doc share policy check", {
562
791
  peerId,
563
792
  documentId,
564
793
  isRequested
565
794
  }, {
566
- F: __dxlog_file4,
567
- L: 116,
795
+ F: __dxlog_file5,
796
+ L: 124,
568
797
  S: this,
569
798
  C: (f, a) => f(...a)
570
799
  });
@@ -573,26 +802,26 @@ var AutomergeHost = class {
573
802
  try {
574
803
  const spaceKey = getSpaceKeyFromDoc(doc);
575
804
  if (!spaceKey) {
576
- log3("space key not found for share policy check", {
805
+ log4("space key not found for share policy check", {
577
806
  peerId,
578
807
  documentId
579
808
  }, {
580
- F: __dxlog_file4,
581
- L: 123,
809
+ F: __dxlog_file5,
810
+ L: 131,
582
811
  S: this,
583
812
  C: (f, a) => f(...a)
584
813
  });
585
814
  return false;
586
815
  }
587
816
  const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
588
- const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
817
+ const deviceKeyHex = peerMetadata?.dxos_deviceKey;
589
818
  if (!deviceKeyHex) {
590
- log3("device key not found for share policy check", {
819
+ log4("device key not found for share policy check", {
591
820
  peerId,
592
821
  documentId
593
822
  }, {
594
- F: __dxlog_file4,
595
- L: 132,
823
+ F: __dxlog_file5,
824
+ L: 140,
596
825
  S: this,
597
826
  C: (f, a) => f(...a)
598
827
  });
@@ -600,7 +829,7 @@ var AutomergeHost = class {
600
829
  }
601
830
  const deviceKey = PublicKey.from(deviceKeyHex);
602
831
  const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
603
- log3("share policy check", {
832
+ log4("share policy check", {
604
833
  localPeer: this._peerId,
605
834
  remotePeer: peerId,
606
835
  documentId,
@@ -608,16 +837,16 @@ var AutomergeHost = class {
608
837
  spaceKey,
609
838
  isAuthorized
610
839
  }, {
611
- F: __dxlog_file4,
612
- L: 138,
840
+ F: __dxlog_file5,
841
+ L: 146,
613
842
  S: this,
614
843
  C: (f, a) => f(...a)
615
844
  });
616
845
  return isAuthorized;
617
846
  } catch (err) {
618
- log3.catch(err, void 0, {
619
- F: __dxlog_file4,
620
- L: 148,
847
+ log4.catch(err, void 0, {
848
+ F: __dxlog_file5,
849
+ L: 156,
621
850
  S: this,
622
851
  C: (f, a) => f(...a)
623
852
  });
@@ -627,16 +856,25 @@ var AutomergeHost = class {
627
856
  });
628
857
  this._clientNetwork.ready();
629
858
  this._meshNetwork.ready();
859
+ await this._echoNetworkAdapter.open();
630
860
  await this._clientNetwork.whenConnected();
861
+ await this._echoNetworkAdapter.whenConnected();
631
862
  }
632
863
  async close() {
633
864
  await this._storage.close?.();
634
865
  await this._clientNetwork.close();
866
+ await this._echoNetworkAdapter.close();
635
867
  await this._ctx.dispose();
636
868
  }
637
869
  get repo() {
638
870
  return this._repo;
639
871
  }
872
+ async addReplicator(replicator) {
873
+ await this._echoNetworkAdapter.addReplicator(replicator);
874
+ }
875
+ async removeReplicator(replicator) {
876
+ await this._echoNetworkAdapter.removeReplicator(replicator);
877
+ }
640
878
  async _beforeSave({ path, batch }) {
641
879
  const handle = this._repo.handles[path[0]];
642
880
  if (!handle) {
@@ -694,9 +932,9 @@ var AutomergeHost = class {
694
932
  //
695
933
  async flush({ states }) {
696
934
  await Promise.all(states?.map(async ({ heads, documentId }) => {
697
- invariant3(heads, "heads are required for flush", {
698
- F: __dxlog_file4,
699
- L: 233,
935
+ invariant4(heads, "heads are required for flush", {
936
+ F: __dxlog_file5,
937
+ L: 252,
700
938
  S: this,
701
939
  A: [
702
940
  "heads",
@@ -724,37 +962,37 @@ var AutomergeHost = class {
724
962
  return this._meshNetwork.createExtension();
725
963
  }
726
964
  authorizeDevice(spaceKey, deviceKey) {
727
- log3("authorizeDevice", {
965
+ log4("authorizeDevice", {
728
966
  spaceKey,
729
967
  deviceKey
730
968
  }, {
731
- F: __dxlog_file4,
732
- L: 263,
969
+ F: __dxlog_file5,
970
+ L: 282,
733
971
  S: this,
734
972
  C: (f, a) => f(...a)
735
973
  });
736
974
  defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);
737
975
  }
738
976
  };
739
- _ts_decorate([
977
+ _ts_decorate2([
740
978
  trace.info()
741
979
  ], AutomergeHost.prototype, "_peerId", void 0);
742
- _ts_decorate([
980
+ _ts_decorate2([
743
981
  trace.info({
744
982
  depth: null
745
983
  })
746
984
  ], AutomergeHost.prototype, "_automergeDocs", null);
747
- _ts_decorate([
985
+ _ts_decorate2([
748
986
  trace.info({
749
987
  depth: null
750
988
  })
751
989
  ], AutomergeHost.prototype, "_automergePeers", null);
752
- _ts_decorate([
990
+ _ts_decorate2([
753
991
  trace.span({
754
992
  showInBrowserTimeline: true
755
993
  })
756
994
  ], AutomergeHost.prototype, "flush", null);
757
- AutomergeHost = _ts_decorate([
995
+ AutomergeHost = _ts_decorate2([
758
996
  trace.resource()
759
997
  ], AutomergeHost);
760
998
  var getSpaceKeyFromDoc = (doc) => {
@@ -787,10 +1025,10 @@ var changeIsPresentInDoc = (doc, changeHash) => {
787
1025
  import { Event as Event2 } from "@dxos/async";
788
1026
  import { cancelWithContext } from "@dxos/context";
789
1027
  import { warnAfterTimeout } from "@dxos/debug";
790
- import { invariant as invariant4 } from "@dxos/invariant";
791
- import { log as log4 } from "@dxos/log";
1028
+ import { invariant as invariant5 } from "@dxos/invariant";
1029
+ import { log as log5 } from "@dxos/log";
792
1030
  import { trace as trace2 } from "@dxos/tracing";
793
- function _ts_decorate2(decorators, target, key, desc) {
1031
+ function _ts_decorate3(decorators, target, key, desc) {
794
1032
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
795
1033
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
796
1034
  r = Reflect.decorate(decorators, target, key, desc);
@@ -800,7 +1038,7 @@ function _ts_decorate2(decorators, target, key, desc) {
800
1038
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
801
1039
  return c > 3 && r && Object.defineProperty(target, key, r), r;
802
1040
  }
803
- 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";
804
1042
  var AutomergeDocumentLoaderImpl = class {
805
1043
  constructor(_spaceKey, _repo) {
806
1044
  this._spaceKey = _spaceKey;
@@ -811,20 +1049,21 @@ var AutomergeDocumentLoaderImpl = class {
811
1049
  this.onObjectDocumentLoaded = new Event2();
812
1050
  }
813
1051
  getAllHandles() {
814
- return [
1052
+ return this._spaceRootDocHandle != null ? [
1053
+ this._spaceRootDocHandle,
815
1054
  ...new Set(this._objectDocumentHandles.values())
816
- ];
1055
+ ] : [];
817
1056
  }
818
1057
  async loadSpaceRootDocHandle(ctx, spaceState) {
819
1058
  if (this._spaceRootDocHandle != null) {
820
1059
  return;
821
1060
  }
822
1061
  if (!spaceState.rootUrl) {
823
- log4.error("Database opened with no rootUrl", {
1062
+ log5.error("Database opened with no rootUrl", {
824
1063
  spaceKey: this._spaceKey
825
1064
  }, {
826
- F: __dxlog_file5,
827
- L: 68,
1065
+ F: __dxlog_file6,
1066
+ L: 70,
828
1067
  S: this,
829
1068
  C: (f, a) => f(...a)
830
1069
  });
@@ -832,9 +1071,9 @@ var AutomergeDocumentLoaderImpl = class {
832
1071
  } else {
833
1072
  const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
834
1073
  const doc = existingDocHandle.docSync();
835
- invariant4(doc, void 0, {
836
- F: __dxlog_file5,
837
- L: 73,
1074
+ invariant5(doc, void 0, {
1075
+ F: __dxlog_file6,
1076
+ L: 75,
838
1077
  S: this,
839
1078
  A: [
840
1079
  "doc",
@@ -854,9 +1093,9 @@ var AutomergeDocumentLoaderImpl = class {
854
1093
  let hasUrlsToLoad = false;
855
1094
  const urlsToLoad = {};
856
1095
  for (const objectId of objectIds) {
857
- invariant4(this._spaceRootDocHandle, void 0, {
858
- F: __dxlog_file5,
859
- L: 86,
1096
+ invariant5(this._spaceRootDocHandle, void 0, {
1097
+ F: __dxlog_file6,
1098
+ L: 88,
860
1099
  S: this,
861
1100
  A: [
862
1101
  "this._spaceRootDocHandle",
@@ -867,9 +1106,9 @@ var AutomergeDocumentLoaderImpl = class {
867
1106
  continue;
868
1107
  }
869
1108
  const spaceRootDoc = this._spaceRootDocHandle.docSync();
870
- invariant4(spaceRootDoc, void 0, {
871
- F: __dxlog_file5,
872
- L: 91,
1109
+ invariant5(spaceRootDoc, void 0, {
1110
+ F: __dxlog_file6,
1111
+ L: 93,
873
1112
  S: this,
874
1113
  A: [
875
1114
  "spaceRootDoc",
@@ -879,11 +1118,11 @@ var AutomergeDocumentLoaderImpl = class {
879
1118
  const documentUrl = (spaceRootDoc.links ?? {})[objectId];
880
1119
  if (documentUrl == null) {
881
1120
  this._objectsPendingDocumentLoad.add(objectId);
882
- log4.info("loading delayed until object links are initialized", {
1121
+ log5.info("loading delayed until object links are initialized", {
883
1122
  objectId
884
1123
  }, {
885
- F: __dxlog_file5,
886
- L: 95,
1124
+ F: __dxlog_file6,
1125
+ L: 97,
887
1126
  S: this,
888
1127
  C: (f, a) => f(...a)
889
1128
  });
@@ -905,9 +1144,9 @@ var AutomergeDocumentLoaderImpl = class {
905
1144
  linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
906
1145
  }
907
1146
  getSpaceRootDocHandle() {
908
- invariant4(this._spaceRootDocHandle, void 0, {
909
- F: __dxlog_file5,
910
- L: 118,
1147
+ invariant5(this._spaceRootDocHandle, void 0, {
1148
+ F: __dxlog_file6,
1149
+ L: 120,
911
1150
  S: this,
912
1151
  A: [
913
1152
  "this._spaceRootDocHandle",
@@ -917,9 +1156,9 @@ var AutomergeDocumentLoaderImpl = class {
917
1156
  return this._spaceRootDocHandle;
918
1157
  }
919
1158
  createDocumentForObject(objectId) {
920
- invariant4(this._spaceRootDocHandle, void 0, {
921
- F: __dxlog_file5,
922
- L: 123,
1159
+ invariant5(this._spaceRootDocHandle, void 0, {
1160
+ F: __dxlog_file6,
1161
+ L: 125,
923
1162
  S: this,
924
1163
  A: [
925
1164
  "this._spaceRootDocHandle",
@@ -957,30 +1196,30 @@ var AutomergeDocumentLoaderImpl = class {
957
1196
  };
958
1197
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
959
1198
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
960
- 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", {
961
1200
  ...logMeta,
962
1201
  actualDocumentUrl: objectDocumentHandle.url
963
1202
  }, {
964
- F: __dxlog_file5,
965
- L: 153,
1203
+ F: __dxlog_file6,
1204
+ L: 155,
966
1205
  S: this,
967
1206
  C: (f, a) => f(...a)
968
1207
  });
969
1208
  continue;
970
1209
  }
971
1210
  if (objectDocumentHandle?.url === automergeUrl) {
972
- log4.warn("object document was already loaded", logMeta, {
973
- F: __dxlog_file5,
974
- L: 160,
1211
+ log5.warn("object document was already loaded", logMeta, {
1212
+ F: __dxlog_file6,
1213
+ L: 162,
975
1214
  S: this,
976
1215
  C: (f, a) => f(...a)
977
1216
  });
978
1217
  continue;
979
1218
  }
980
1219
  const handle = this._repo.find(automergeUrl);
981
- log4.debug("document loading triggered", logMeta, {
982
- F: __dxlog_file5,
983
- L: 164,
1220
+ log5.debug("document loading triggered", logMeta, {
1221
+ F: __dxlog_file6,
1222
+ L: 166,
984
1223
  S: this,
985
1224
  C: (f, a) => f(...a)
986
1225
  });
@@ -998,12 +1237,12 @@ var AutomergeDocumentLoaderImpl = class {
998
1237
  break;
999
1238
  } catch (err) {
1000
1239
  if (`${err}`.includes("Timeout")) {
1001
- log4.info("wraparound", {
1240
+ log5.info("wraparound", {
1002
1241
  id: docHandle.documentId,
1003
1242
  state: docHandle.state
1004
1243
  }, {
1005
- F: __dxlog_file5,
1006
- L: 180,
1244
+ F: __dxlog_file6,
1245
+ L: 182,
1007
1246
  S: this,
1008
1247
  C: (f, a) => f(...a)
1009
1248
  });
@@ -1043,9 +1282,9 @@ var AutomergeDocumentLoaderImpl = class {
1043
1282
  docUrl: handle.url
1044
1283
  };
1045
1284
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
1046
- log4.info("document loaded after all listeners were removed", logMeta, {
1047
- F: __dxlog_file5,
1048
- L: 216,
1285
+ log5.info("document loaded after all listeners were removed", logMeta, {
1286
+ F: __dxlog_file6,
1287
+ L: 218,
1049
1288
  S: this,
1050
1289
  C: (f, a) => f(...a)
1051
1290
  });
@@ -1053,9 +1292,9 @@ var AutomergeDocumentLoaderImpl = class {
1053
1292
  }
1054
1293
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
1055
1294
  if (objectDocHandle?.url !== handle.url) {
1056
- log4.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1057
- F: __dxlog_file5,
1058
- L: 221,
1295
+ log5.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1296
+ F: __dxlog_file6,
1297
+ L: 223,
1059
1298
  S: this,
1060
1299
  C: (f, a) => f(...a)
1061
1300
  });
@@ -1067,14 +1306,14 @@ var AutomergeDocumentLoaderImpl = class {
1067
1306
  });
1068
1307
  } catch (err) {
1069
1308
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1070
- log4.warn("failed to load a document", {
1309
+ log5.warn("failed to load a document", {
1071
1310
  objectId,
1072
1311
  automergeUrl: handle.url,
1073
1312
  retryLoading: shouldRetryLoading,
1074
1313
  err
1075
1314
  }, {
1076
- F: __dxlog_file5,
1077
- L: 227,
1315
+ F: __dxlog_file6,
1316
+ L: 229,
1078
1317
  S: this,
1079
1318
  C: (f, a) => f(...a)
1080
1319
  });
@@ -1084,12 +1323,12 @@ var AutomergeDocumentLoaderImpl = class {
1084
1323
  }
1085
1324
  }
1086
1325
  };
1087
- _ts_decorate2([
1326
+ _ts_decorate3([
1088
1327
  trace2.span({
1089
1328
  showInBrowserTimeline: true
1090
1329
  })
1091
1330
  ], AutomergeDocumentLoaderImpl.prototype, "loadSpaceRootDocHandle", null);
1092
- AutomergeDocumentLoaderImpl = _ts_decorate2([
1331
+ AutomergeDocumentLoaderImpl = _ts_decorate3([
1093
1332
  trace2.resource()
1094
1333
  ], AutomergeDocumentLoaderImpl);
1095
1334
  export {