@dxos/echo-pipeline 0.6.2-main.8a232a5 → 0.6.2-main.d41f0d2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/lib/browser/{chunk-UJQ5VS5V.mjs → chunk-SJUDZ3CQ.mjs} +17 -7
  2. package/dist/lib/browser/chunk-SJUDZ3CQ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +562 -57
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-RH6TDRML.cjs → chunk-NLHNTXVQ.cjs} +20 -10
  8. package/dist/lib/node/chunk-NLHNTXVQ.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +582 -79
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +11 -11
  13. package/dist/types/src/automerge/automerge-doc-loader.d.ts +71 -0
  14. package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -0
  15. package/dist/types/src/automerge/automerge-doc-loader.test.d.ts +2 -0
  16. package/dist/types/src/automerge/automerge-doc-loader.test.d.ts.map +1 -0
  17. package/dist/types/src/automerge/automerge-host.d.ts +17 -2
  18. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  19. package/dist/types/src/automerge/echo-network-adapter.d.ts +1 -1
  20. package/dist/types/src/automerge/index.d.ts +2 -0
  21. package/dist/types/src/automerge/index.d.ts.map +1 -1
  22. package/dist/types/src/automerge/local-host-network-adapter.d.ts +30 -0
  23. package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -0
  24. package/dist/types/src/db-host/data-service.d.ts +5 -2
  25. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  26. package/dist/types/src/db-host/documents-synchronizer.d.ts +1 -1
  27. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  28. package/package.json +33 -33
  29. package/src/automerge/automerge-doc-loader.test.ts +103 -0
  30. package/src/automerge/automerge-doc-loader.ts +267 -0
  31. package/src/automerge/automerge-host.ts +56 -6
  32. package/src/automerge/automerge-repo.test.ts +1 -124
  33. package/src/automerge/echo-network-adapter.ts +1 -1
  34. package/src/automerge/index.ts +2 -0
  35. package/src/automerge/local-host-network-adapter.ts +115 -0
  36. package/src/db-host/data-service.ts +20 -3
  37. package/src/db-host/documents-synchronizer.test.ts +1 -1
  38. package/src/db-host/documents-synchronizer.ts +1 -1
  39. package/dist/lib/browser/chunk-UJQ5VS5V.mjs.map +0 -7
  40. package/dist/lib/node/chunk-RH6TDRML.cjs.map +0 -7
@@ -18,39 +18,41 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var node_exports = {};
20
20
  __export(node_exports, {
21
- AuthExtension: () => import_chunk_RH6TDRML.AuthExtension,
22
- AuthStatus: () => import_chunk_RH6TDRML.AuthStatus,
21
+ AuthExtension: () => import_chunk_NLHNTXVQ.AuthExtension,
22
+ AuthStatus: () => import_chunk_NLHNTXVQ.AuthStatus,
23
+ AutomergeDocumentLoaderImpl: () => AutomergeDocumentLoaderImpl,
23
24
  AutomergeHost: () => AutomergeHost,
24
- CredentialRetrieverExtension: () => import_chunk_RH6TDRML.CredentialRetrieverExtension,
25
- CredentialServerExtension: () => import_chunk_RH6TDRML.CredentialServerExtension,
26
- DataServiceImpl: () => import_chunk_RH6TDRML.DataServiceImpl,
27
- DocumentsSynchronizer: () => import_chunk_RH6TDRML.DocumentsSynchronizer,
25
+ CredentialRetrieverExtension: () => import_chunk_NLHNTXVQ.CredentialRetrieverExtension,
26
+ CredentialServerExtension: () => import_chunk_NLHNTXVQ.CredentialServerExtension,
27
+ DataServiceImpl: () => import_chunk_NLHNTXVQ.DataServiceImpl,
28
+ DocumentsSynchronizer: () => import_chunk_NLHNTXVQ.DocumentsSynchronizer,
28
29
  LevelDBStorageAdapter: () => LevelDBStorageAdapter,
29
- MOCK_AUTH_PROVIDER: () => import_chunk_RH6TDRML.MOCK_AUTH_PROVIDER,
30
- MOCK_AUTH_VERIFIER: () => import_chunk_RH6TDRML.MOCK_AUTH_VERIFIER,
30
+ LocalHostNetworkAdapter: () => LocalHostNetworkAdapter,
31
+ MOCK_AUTH_PROVIDER: () => import_chunk_NLHNTXVQ.MOCK_AUTH_PROVIDER,
32
+ MOCK_AUTH_VERIFIER: () => import_chunk_NLHNTXVQ.MOCK_AUTH_VERIFIER,
31
33
  MeshEchoReplicator: () => MeshEchoReplicator,
32
- MetadataStore: () => import_chunk_RH6TDRML.MetadataStore,
33
- Pipeline: () => import_chunk_RH6TDRML.Pipeline,
34
- SnapshotManager: () => import_chunk_RH6TDRML.SnapshotManager,
35
- SnapshotStore: () => import_chunk_RH6TDRML.SnapshotStore,
36
- Space: () => import_chunk_RH6TDRML.Space,
37
- SpaceManager: () => import_chunk_RH6TDRML.SpaceManager,
38
- SpaceProtocol: () => import_chunk_RH6TDRML.SpaceProtocol,
39
- SpaceProtocolSession: () => import_chunk_RH6TDRML.SpaceProtocolSession,
40
- TimeframeClock: () => import_chunk_RH6TDRML.TimeframeClock,
41
- codec: () => import_chunk_RH6TDRML.codec,
42
- createIdFromSpaceKey: () => import_chunk_RH6TDRML.createIdFromSpaceKey,
43
- createMappedFeedWriter: () => import_chunk_RH6TDRML.createMappedFeedWriter,
34
+ MetadataStore: () => import_chunk_NLHNTXVQ.MetadataStore,
35
+ Pipeline: () => import_chunk_NLHNTXVQ.Pipeline,
36
+ SnapshotManager: () => import_chunk_NLHNTXVQ.SnapshotManager,
37
+ SnapshotStore: () => import_chunk_NLHNTXVQ.SnapshotStore,
38
+ Space: () => import_chunk_NLHNTXVQ.Space,
39
+ SpaceManager: () => import_chunk_NLHNTXVQ.SpaceManager,
40
+ SpaceProtocol: () => import_chunk_NLHNTXVQ.SpaceProtocol,
41
+ SpaceProtocolSession: () => import_chunk_NLHNTXVQ.SpaceProtocolSession,
42
+ TimeframeClock: () => import_chunk_NLHNTXVQ.TimeframeClock,
43
+ codec: () => import_chunk_NLHNTXVQ.codec,
44
+ createIdFromSpaceKey: () => import_chunk_NLHNTXVQ.createIdFromSpaceKey,
45
+ createMappedFeedWriter: () => import_chunk_NLHNTXVQ.createMappedFeedWriter,
44
46
  encodingOptions: () => encodingOptions,
45
47
  getSpaceKeyFromDoc: () => getSpaceKeyFromDoc,
46
- hasInvitationExpired: () => import_chunk_RH6TDRML.hasInvitationExpired,
47
- mapFeedIndexesToTimeframe: () => import_chunk_RH6TDRML.mapFeedIndexesToTimeframe,
48
- mapTimeframeToFeedIndexes: () => import_chunk_RH6TDRML.mapTimeframeToFeedIndexes,
49
- startAfter: () => import_chunk_RH6TDRML.startAfter,
50
- valueEncoding: () => import_chunk_RH6TDRML.valueEncoding
48
+ hasInvitationExpired: () => import_chunk_NLHNTXVQ.hasInvitationExpired,
49
+ mapFeedIndexesToTimeframe: () => import_chunk_NLHNTXVQ.mapFeedIndexesToTimeframe,
50
+ mapTimeframeToFeedIndexes: () => import_chunk_NLHNTXVQ.mapTimeframeToFeedIndexes,
51
+ startAfter: () => import_chunk_NLHNTXVQ.startAfter,
52
+ valueEncoding: () => import_chunk_NLHNTXVQ.valueEncoding
51
53
  });
52
54
  module.exports = __toCommonJS(node_exports);
53
- var import_chunk_RH6TDRML = require("./chunk-RH6TDRML.cjs");
55
+ var import_chunk_NLHNTXVQ = require("./chunk-NLHNTXVQ.cjs");
54
56
  var import_async = require("@dxos/async");
55
57
  var import_automerge = require("@dxos/automerge/automerge");
56
58
  var import_automerge_repo = require("@dxos/automerge/automerge-repo");
@@ -68,14 +70,26 @@ var import_invariant2 = require("@dxos/invariant");
68
70
  var import_log2 = require("@dxos/log");
69
71
  var import_indexing = require("@dxos/indexing");
70
72
  var import_context3 = require("@dxos/context");
71
- var import_invariant3 = require("@dxos/invariant");
72
- var import_keys2 = require("@dxos/keys");
73
- var import_log3 = require("@dxos/log");
74
- var import_util2 = require("@dxos/util");
73
+ var import_async3 = require("@dxos/async");
75
74
  var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
75
+ var import_codec_protobuf = require("@dxos/codec-protobuf");
76
+ var import_invariant3 = require("@dxos/invariant");
77
+ var import_async4 = require("@dxos/async");
78
+ var import_automerge_repo4 = require("@dxos/automerge/automerge-repo");
76
79
  var import_context4 = require("@dxos/context");
80
+ var import_debug = require("@dxos/debug");
81
+ var import_echo_protocol = require("@dxos/echo-protocol");
77
82
  var import_invariant4 = require("@dxos/invariant");
83
+ var import_log3 = require("@dxos/log");
84
+ var import_tracing2 = require("@dxos/tracing");
85
+ var import_invariant5 = require("@dxos/invariant");
86
+ var import_keys2 = require("@dxos/keys");
78
87
  var import_log4 = require("@dxos/log");
88
+ var import_util2 = require("@dxos/util");
89
+ var import_automerge_repo5 = require("@dxos/automerge/automerge-repo");
90
+ var import_context5 = require("@dxos/context");
91
+ var import_invariant6 = require("@dxos/invariant");
92
+ var import_log5 = require("@dxos/log");
79
93
  var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
80
94
  function _ts_decorate(decorators, target, key, desc) {
81
95
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -137,7 +151,7 @@ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
137
151
  }
138
152
  async close() {
139
153
  if (this._lifecycleState === import_context2.LifecycleState.CLOSED) {
140
- return this;
154
+ return;
141
155
  }
142
156
  for (const replicator of this._replicators) {
143
157
  await replicator.disconnect();
@@ -480,6 +494,138 @@ var encodingOptions = {
480
494
  valueEncoding: "buffer"
481
495
  };
482
496
  var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
497
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
498
+ var LocalHostNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
499
+ constructor() {
500
+ super(...arguments);
501
+ this._peers = /* @__PURE__ */ new Map();
502
+ this._connected = new import_async3.Trigger();
503
+ this._isConnected = false;
504
+ }
505
+ /**
506
+ * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
507
+ */
508
+ ready() {
509
+ this.emit("ready", {
510
+ network: this
511
+ });
512
+ }
513
+ /**
514
+ * Called by `Repo` to connect to the network.
515
+ *
516
+ * @param peerId Our peer Id.
517
+ */
518
+ connect(peerId) {
519
+ this.peerId = peerId;
520
+ this._isConnected = true;
521
+ this._connected.wake();
522
+ }
523
+ send(message) {
524
+ const peer = this._peers.get(message.targetId);
525
+ (0, import_invariant3.invariant)(peer, "Peer not found.", {
526
+ F: __dxlog_file2,
527
+ L: 51,
528
+ S: this,
529
+ A: [
530
+ "peer",
531
+ "'Peer not found.'"
532
+ ]
533
+ });
534
+ peer.send(message);
535
+ }
536
+ async close() {
537
+ this._peers.forEach((peer) => peer.disconnect());
538
+ this.emit("close");
539
+ }
540
+ disconnect() {
541
+ }
542
+ async whenConnected() {
543
+ await this._connected.wait({
544
+ timeout: 1e4
545
+ });
546
+ }
547
+ syncRepo({ id, syncMessage }) {
548
+ const peerId = this._getPeerId(id);
549
+ return new import_codec_protobuf.Stream(({ next, close }) => {
550
+ (0, import_invariant3.invariant)(!this._peers.has(peerId), "Peer already connected.", {
551
+ F: __dxlog_file2,
552
+ L: 73,
553
+ S: this,
554
+ A: [
555
+ "!this._peers.has(peerId)",
556
+ "'Peer already connected.'"
557
+ ]
558
+ });
559
+ this._peers.set(peerId, {
560
+ connected: true,
561
+ send: (message) => {
562
+ next({
563
+ syncMessage: import_automerge_repo3.cbor.encode(message)
564
+ });
565
+ },
566
+ disconnect: () => {
567
+ this._peers.delete(peerId);
568
+ close();
569
+ this.emit("peer-disconnected", {
570
+ peerId
571
+ });
572
+ }
573
+ });
574
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
575
+ F: __dxlog_file2,
576
+ L: 90,
577
+ S: this,
578
+ A: [
579
+ "this._isConnected",
580
+ ""
581
+ ]
582
+ });
583
+ this.emit("peer-candidate", {
584
+ peerMetadata: {},
585
+ peerId
586
+ });
587
+ });
588
+ }
589
+ async sendSyncMessage({ id, syncMessage }) {
590
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
591
+ F: __dxlog_file2,
592
+ L: 99,
593
+ S: this,
594
+ A: [
595
+ "this._isConnected",
596
+ ""
597
+ ]
598
+ });
599
+ const message = import_automerge_repo3.cbor.decode(syncMessage);
600
+ this.emit("message", message);
601
+ }
602
+ async getHostInfo() {
603
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
604
+ F: __dxlog_file2,
605
+ L: 105,
606
+ S: this,
607
+ A: [
608
+ "this._isConnected",
609
+ ""
610
+ ]
611
+ });
612
+ (0, import_invariant3.invariant)(this.peerId, "Peer id not set.", {
613
+ F: __dxlog_file2,
614
+ L: 106,
615
+ S: this,
616
+ A: [
617
+ "this.peerId",
618
+ "'Peer id not set.'"
619
+ ]
620
+ });
621
+ return {
622
+ peerId: this.peerId
623
+ };
624
+ }
625
+ _getPeerId(id) {
626
+ return id;
627
+ }
628
+ };
483
629
  function _ts_decorate2(decorators, target, key, desc) {
484
630
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
485
631
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -490,7 +636,7 @@ function _ts_decorate2(decorators, target, key, desc) {
490
636
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
491
637
  return c > 3 && r && Object.defineProperty(target, key, r), r;
492
638
  }
493
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
639
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
494
640
  var AutomergeHost = class extends import_context.Resource {
495
641
  constructor({ db, indexMetadataStore }) {
496
642
  super();
@@ -513,20 +659,26 @@ var AutomergeHost = class extends import_context.Resource {
513
659
  async _open() {
514
660
  this._peerId = `host-${import_keys.PublicKey.random().toHex()}`;
515
661
  await this._storage.open?.();
662
+ this._clientNetwork = new LocalHostNetworkAdapter();
516
663
  this._repo = new import_automerge_repo.Repo({
517
664
  peerId: this._peerId,
518
665
  sharePolicy: this._sharePolicy.bind(this),
519
666
  storage: this._storage,
520
667
  network: [
668
+ // Downstream client.
669
+ this._clientNetwork,
521
670
  // Upstream swarm.
522
671
  this._echoNetworkAdapter
523
672
  ]
524
673
  });
674
+ this._clientNetwork.ready();
525
675
  await this._echoNetworkAdapter.open();
676
+ await this._clientNetwork.whenConnected();
526
677
  await this._echoNetworkAdapter.whenConnected();
527
678
  }
528
679
  async _close() {
529
680
  await this._storage.close?.();
681
+ await this._clientNetwork.close();
530
682
  await this._echoNetworkAdapter.close();
531
683
  await this._ctx.dispose();
532
684
  }
@@ -588,8 +740,8 @@ var AutomergeHost = class extends import_context.Resource {
588
740
  return;
589
741
  }
590
742
  const handle = await this.loadDoc(import_context.Context.default(void 0, {
591
- F: __dxlog_file2,
592
- L: 189
743
+ F: __dxlog_file3,
744
+ L: 207
593
745
  }), documentId);
594
746
  await waitForHeads(handle, heads2);
595
747
  }) ?? []);
@@ -600,8 +752,8 @@ var AutomergeHost = class extends import_context.Resource {
600
752
  import_log.log.info("re-indexing heads for document", {
601
753
  documentId
602
754
  }, {
603
- F: __dxlog_file2,
604
- L: 200,
755
+ F: __dxlog_file3,
756
+ L: 218,
605
757
  S: this,
606
758
  C: (f, a) => f(...a)
607
759
  });
@@ -616,8 +768,8 @@ var AutomergeHost = class extends import_context.Resource {
616
768
  import_log.log.warn("document is not available locally, skipping", {
617
769
  documentId
618
770
  }, {
619
- F: __dxlog_file2,
620
- L: 204,
771
+ F: __dxlog_file3,
772
+ L: 222,
621
773
  S: this,
622
774
  C: (f, a) => f(...a)
623
775
  });
@@ -625,8 +777,8 @@ var AutomergeHost = class extends import_context.Resource {
625
777
  }
626
778
  const doc = handle.docSync();
627
779
  (0, import_invariant.invariant)(doc, void 0, {
628
- F: __dxlog_file2,
629
- L: 209,
780
+ F: __dxlog_file3,
781
+ L: 227,
630
782
  S: this,
631
783
  A: [
632
784
  "doc",
@@ -639,8 +791,8 @@ var AutomergeHost = class extends import_context.Resource {
639
791
  await batch.write();
640
792
  }
641
793
  import_log.log.info("done re-indexing heads", void 0, {
642
- F: __dxlog_file2,
643
- L: 216,
794
+ F: __dxlog_file3,
795
+ L: 234,
644
796
  S: this,
645
797
  C: (f, a) => f(...a)
646
798
  });
@@ -733,8 +885,17 @@ var AutomergeHost = class extends import_context.Resource {
733
885
  /**
734
886
  * Flush documents to disk.
735
887
  */
736
- async flush({ documentIds } = {}) {
737
- await this._repo.flush(documentIds);
888
+ async flush({ states } = {}) {
889
+ if (states) {
890
+ await Promise.all(states.map(async ({ heads, documentId }) => {
891
+ if (!heads) {
892
+ return;
893
+ }
894
+ const handle = this._repo.handles[documentId] ?? this._repo.find(documentId);
895
+ await waitForHeads(handle, heads);
896
+ }) ?? []);
897
+ }
898
+ await this._repo.flush(states?.map(({ documentId }) => documentId));
738
899
  }
739
900
  async getHeads(documentId) {
740
901
  const handle = this._repo.handles[documentId];
@@ -748,6 +909,24 @@ var AutomergeHost = class extends import_context.Resource {
748
909
  return this._headsStore.getHeads(documentId);
749
910
  }
750
911
  }
912
+ /**
913
+ * Host <-> Client sync.
914
+ */
915
+ syncRepo(request) {
916
+ return this._clientNetwork.syncRepo(request);
917
+ }
918
+ /**
919
+ * Host <-> Client sync.
920
+ */
921
+ sendSyncMessage(request) {
922
+ return this._clientNetwork.sendSyncMessage(request);
923
+ }
924
+ /**
925
+ * Host <-> Client sync.
926
+ */
927
+ async getHostInfo() {
928
+ return this._clientNetwork.getHostInfo();
929
+ }
751
930
  };
752
931
  _ts_decorate2([
753
932
  import_tracing.trace.info()
@@ -792,9 +971,331 @@ var waitForHeads = async (handle, heads) => {
792
971
  var changeIsPresentInDoc = (doc, changeHash) => {
793
972
  return !!(0, import_automerge.getBackend)(doc).getChangeByHash(changeHash);
794
973
  };
795
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
974
+ function _ts_decorate3(decorators, target, key, desc) {
975
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
976
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
977
+ r = Reflect.decorate(decorators, target, key, desc);
978
+ else
979
+ for (var i = decorators.length - 1; i >= 0; i--)
980
+ if (d = decorators[i])
981
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
982
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
983
+ }
984
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
985
+ var AutomergeDocumentLoaderImpl = class {
986
+ constructor(_spaceId, _repo, _spaceKey) {
987
+ this._spaceId = _spaceId;
988
+ this._repo = _repo;
989
+ this._spaceKey = _spaceKey;
990
+ this._spaceRootDocHandle = null;
991
+ this._objectDocumentHandles = /* @__PURE__ */ new Map();
992
+ this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
993
+ this.onObjectDocumentLoaded = new import_async4.Event();
994
+ }
995
+ getAllHandles() {
996
+ return this._spaceRootDocHandle != null ? [
997
+ this._spaceRootDocHandle,
998
+ ...new Set(this._objectDocumentHandles.values())
999
+ ] : [];
1000
+ }
1001
+ async loadSpaceRootDocHandle(ctx, spaceState) {
1002
+ if (this._spaceRootDocHandle != null) {
1003
+ return;
1004
+ }
1005
+ if (!spaceState.rootUrl) {
1006
+ throw new Error("Database opened with no rootUrl");
1007
+ }
1008
+ const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
1009
+ const doc = existingDocHandle.docSync();
1010
+ (0, import_invariant4.invariant)(doc, void 0, {
1011
+ F: __dxlog_file4,
1012
+ L: 84,
1013
+ S: this,
1014
+ A: [
1015
+ "doc",
1016
+ ""
1017
+ ]
1018
+ });
1019
+ (0, import_invariant4.invariant)(doc.version === import_echo_protocol.SpaceDocVersion.CURRENT, void 0, {
1020
+ F: __dxlog_file4,
1021
+ L: 85,
1022
+ S: this,
1023
+ A: [
1024
+ "doc.version === SpaceDocVersion.CURRENT",
1025
+ ""
1026
+ ]
1027
+ });
1028
+ if (doc.access == null) {
1029
+ this._initDocAccess(existingDocHandle);
1030
+ }
1031
+ this._spaceRootDocHandle = existingDocHandle;
1032
+ }
1033
+ loadObjectDocument(objectIdOrMany) {
1034
+ const objectIds = Array.isArray(objectIdOrMany) ? objectIdOrMany : [
1035
+ objectIdOrMany
1036
+ ];
1037
+ let hasUrlsToLoad = false;
1038
+ const urlsToLoad = {};
1039
+ for (const objectId of objectIds) {
1040
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
1041
+ F: __dxlog_file4,
1042
+ L: 97,
1043
+ S: this,
1044
+ A: [
1045
+ "this._spaceRootDocHandle",
1046
+ ""
1047
+ ]
1048
+ });
1049
+ if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {
1050
+ continue;
1051
+ }
1052
+ const spaceRootDoc = this._spaceRootDocHandle.docSync();
1053
+ (0, import_invariant4.invariant)(spaceRootDoc, void 0, {
1054
+ F: __dxlog_file4,
1055
+ L: 102,
1056
+ S: this,
1057
+ A: [
1058
+ "spaceRootDoc",
1059
+ ""
1060
+ ]
1061
+ });
1062
+ const documentUrl = (spaceRootDoc.links ?? {})[objectId];
1063
+ if (documentUrl == null) {
1064
+ this._objectsPendingDocumentLoad.add(objectId);
1065
+ import_log3.log.info("loading delayed until object links are initialized", {
1066
+ objectId
1067
+ }, {
1068
+ F: __dxlog_file4,
1069
+ L: 106,
1070
+ S: this,
1071
+ C: (f, a) => f(...a)
1072
+ });
1073
+ } else {
1074
+ urlsToLoad[objectId] = documentUrl;
1075
+ hasUrlsToLoad = true;
1076
+ }
1077
+ }
1078
+ if (hasUrlsToLoad) {
1079
+ this._loadLinkedObjects(urlsToLoad);
1080
+ }
1081
+ }
1082
+ getObjectDocumentId(objectId) {
1083
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
1084
+ F: __dxlog_file4,
1085
+ L: 118,
1086
+ S: this,
1087
+ A: [
1088
+ "this._spaceRootDocHandle",
1089
+ ""
1090
+ ]
1091
+ });
1092
+ const spaceRootDoc = this._spaceRootDocHandle.docSync();
1093
+ (0, import_invariant4.invariant)(spaceRootDoc, void 0, {
1094
+ F: __dxlog_file4,
1095
+ L: 120,
1096
+ S: this,
1097
+ A: [
1098
+ "spaceRootDoc",
1099
+ ""
1100
+ ]
1101
+ });
1102
+ if (spaceRootDoc.objects?.[objectId]) {
1103
+ return this._spaceRootDocHandle.documentId;
1104
+ }
1105
+ const documentUrl = (spaceRootDoc.links ?? {})[objectId];
1106
+ return documentUrl && (0, import_automerge_repo4.interpretAsDocumentId)(documentUrl);
1107
+ }
1108
+ onObjectLinksUpdated(links) {
1109
+ if (!links) {
1110
+ return;
1111
+ }
1112
+ const linksAwaitingLoad = Object.entries(links).filter(([objectId]) => this._objectsPendingDocumentLoad.has(objectId));
1113
+ this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));
1114
+ linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
1115
+ }
1116
+ getSpaceRootDocHandle() {
1117
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
1118
+ F: __dxlog_file4,
1119
+ L: 140,
1120
+ S: this,
1121
+ A: [
1122
+ "this._spaceRootDocHandle",
1123
+ ""
1124
+ ]
1125
+ });
1126
+ return this._spaceRootDocHandle;
1127
+ }
1128
+ createDocumentForObject(objectId) {
1129
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
1130
+ F: __dxlog_file4,
1131
+ L: 145,
1132
+ S: this,
1133
+ A: [
1134
+ "this._spaceRootDocHandle",
1135
+ ""
1136
+ ]
1137
+ });
1138
+ const spaceDocHandle = this._repo.create({
1139
+ version: import_echo_protocol.SpaceDocVersion.CURRENT
1140
+ });
1141
+ this._initDocAccess(spaceDocHandle);
1142
+ this.onObjectBoundToDocument(spaceDocHandle, objectId);
1143
+ this._spaceRootDocHandle.change((newDoc) => {
1144
+ newDoc.links ??= {};
1145
+ newDoc.links[objectId] = spaceDocHandle.url;
1146
+ });
1147
+ return spaceDocHandle;
1148
+ }
1149
+ onObjectBoundToDocument(handle, objectId) {
1150
+ this._objectDocumentHandles.set(objectId, handle);
1151
+ }
1152
+ clearHandleReferences() {
1153
+ const objectsWithHandles = [
1154
+ ...this._objectDocumentHandles.keys()
1155
+ ];
1156
+ this._objectDocumentHandles.clear();
1157
+ this._spaceRootDocHandle = null;
1158
+ return objectsWithHandles;
1159
+ }
1160
+ _loadLinkedObjects(links) {
1161
+ if (!links) {
1162
+ return;
1163
+ }
1164
+ for (const [objectId, automergeUrl] of Object.entries(links)) {
1165
+ const logMeta = {
1166
+ objectId,
1167
+ automergeUrl
1168
+ };
1169
+ const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
1170
+ if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
1171
+ import_log3.log.warn("object already inlined in a different document, ignoring the link", {
1172
+ ...logMeta,
1173
+ actualDocumentUrl: objectDocumentHandle.url
1174
+ }, {
1175
+ F: __dxlog_file4,
1176
+ L: 177,
1177
+ S: this,
1178
+ C: (f, a) => f(...a)
1179
+ });
1180
+ continue;
1181
+ }
1182
+ if (objectDocumentHandle?.url === automergeUrl) {
1183
+ import_log3.log.warn("object document was already loaded", logMeta, {
1184
+ F: __dxlog_file4,
1185
+ L: 184,
1186
+ S: this,
1187
+ C: (f, a) => f(...a)
1188
+ });
1189
+ continue;
1190
+ }
1191
+ const handle = this._repo.find(automergeUrl);
1192
+ import_log3.log.debug("document loading triggered", logMeta, {
1193
+ F: __dxlog_file4,
1194
+ L: 188,
1195
+ S: this,
1196
+ C: (f, a) => f(...a)
1197
+ });
1198
+ this._objectDocumentHandles.set(objectId, handle);
1199
+ void this._createObjectOnDocumentLoad(handle, objectId);
1200
+ }
1201
+ }
1202
+ async _initDocHandle(ctx, url) {
1203
+ const docHandle = this._repo.find(url);
1204
+ while (true) {
1205
+ try {
1206
+ await (0, import_debug.warnAfterTimeout)(5e3, "Automerge root doc load timeout (CoreDatabase)", async () => {
1207
+ await (0, import_context4.cancelWithContext)(ctx, docHandle.whenReady());
1208
+ });
1209
+ break;
1210
+ } catch (err) {
1211
+ if (`${err}`.includes("Timeout")) {
1212
+ import_log3.log.info("wraparound", {
1213
+ id: docHandle.documentId,
1214
+ state: docHandle.state
1215
+ }, {
1216
+ F: __dxlog_file4,
1217
+ L: 204,
1218
+ S: this,
1219
+ C: (f, a) => f(...a)
1220
+ });
1221
+ continue;
1222
+ }
1223
+ throw err;
1224
+ }
1225
+ }
1226
+ if (docHandle.state === "unavailable") {
1227
+ throw new Error("Automerge document is unavailable");
1228
+ }
1229
+ return docHandle;
1230
+ }
1231
+ _initDocAccess(handle) {
1232
+ handle.change((newDoc) => {
1233
+ newDoc.access ??= {
1234
+ spaceKey: this._spaceKey.toHex()
1235
+ };
1236
+ newDoc.access.spaceKey = this._spaceKey.toHex();
1237
+ });
1238
+ }
1239
+ async _createObjectOnDocumentLoad(handle, objectId) {
1240
+ try {
1241
+ await handle.whenReady();
1242
+ const logMeta = {
1243
+ objectId,
1244
+ docUrl: handle.url
1245
+ };
1246
+ if (this.onObjectDocumentLoaded.listenerCount() === 0) {
1247
+ import_log3.log.info("document loaded after all listeners were removed", logMeta, {
1248
+ F: __dxlog_file4,
1249
+ L: 231,
1250
+ S: this,
1251
+ C: (f, a) => f(...a)
1252
+ });
1253
+ return;
1254
+ }
1255
+ const objectDocHandle = this._objectDocumentHandles.get(objectId);
1256
+ if (objectDocHandle?.url !== handle.url) {
1257
+ import_log3.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1258
+ F: __dxlog_file4,
1259
+ L: 236,
1260
+ S: this,
1261
+ C: (f, a) => f(...a)
1262
+ });
1263
+ return;
1264
+ }
1265
+ this.onObjectDocumentLoaded.emit({
1266
+ handle,
1267
+ objectId
1268
+ });
1269
+ } catch (err) {
1270
+ const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1271
+ import_log3.log.warn("failed to load a document", {
1272
+ objectId,
1273
+ automergeUrl: handle.url,
1274
+ retryLoading: shouldRetryLoading,
1275
+ err
1276
+ }, {
1277
+ F: __dxlog_file4,
1278
+ L: 242,
1279
+ S: this,
1280
+ C: (f, a) => f(...a)
1281
+ });
1282
+ if (shouldRetryLoading) {
1283
+ await this._createObjectOnDocumentLoad(handle, objectId);
1284
+ }
1285
+ }
1286
+ }
1287
+ };
1288
+ _ts_decorate3([
1289
+ import_tracing2.trace.span({
1290
+ showInBrowserTimeline: true
1291
+ })
1292
+ ], AutomergeDocumentLoaderImpl.prototype, "loadSpaceRootDocHandle", null);
1293
+ AutomergeDocumentLoaderImpl = _ts_decorate3([
1294
+ import_tracing2.trace.resource()
1295
+ ], AutomergeDocumentLoaderImpl);
1296
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
796
1297
  var DEFAULT_FACTORY = (params) => new import_teleport_extension_automerge_replicator.AutomergeReplicator(...params);
797
- var MeshReplicatorConnection = class extends import_context4.Resource {
1298
+ var MeshReplicatorConnection = class extends import_context5.Resource {
798
1299
  constructor(_params) {
799
1300
  super();
800
1301
  this._params = _params;
@@ -810,8 +1311,8 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
810
1311
  });
811
1312
  this.writable = new WritableStream({
812
1313
  write: async (message, controller) => {
813
- (0, import_invariant4.invariant)(this._isEnabled, "Writing to a disabled connection", {
814
- F: __dxlog_file3,
1314
+ (0, import_invariant6.invariant)(this._isEnabled, "Writing to a disabled connection", {
1315
+ F: __dxlog_file5,
815
1316
  L: 47,
816
1317
  S: this,
817
1318
  A: [
@@ -821,7 +1322,7 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
821
1322
  });
822
1323
  try {
823
1324
  await this.replicatorExtension.sendSyncMessage({
824
- payload: import_automerge_repo3.cbor.encode(message)
1325
+ payload: import_automerge_repo5.cbor.encode(message)
825
1326
  });
826
1327
  } catch (err) {
827
1328
  controller.error(err);
@@ -838,12 +1339,12 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
838
1339
  onStartReplication: async (info, remotePeerId) => {
839
1340
  this.remoteDeviceKey = remotePeerId;
840
1341
  this._remotePeerId = info.id;
841
- (0, import_log4.log)("onStartReplication", {
1342
+ (0, import_log5.log)("onStartReplication", {
842
1343
  id: info.id,
843
1344
  thisPeerId: this.peerId,
844
1345
  remotePeerId: remotePeerId.toHex()
845
1346
  }, {
846
- F: __dxlog_file3,
1347
+ F: __dxlog_file5,
847
1348
  L: 81,
848
1349
  S: this,
849
1350
  C: (f, a) => f(...a)
@@ -854,7 +1355,7 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
854
1355
  if (!this._isEnabled) {
855
1356
  return;
856
1357
  }
857
- const message = import_automerge_repo3.cbor.decode(payload);
1358
+ const message = import_automerge_repo5.cbor.decode(payload);
858
1359
  readableStreamController.enqueue(message);
859
1360
  },
860
1361
  onClose: async () => {
@@ -869,8 +1370,8 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
869
1370
  }
870
1371
  }
871
1372
  get peerId() {
872
- (0, import_invariant4.invariant)(this._remotePeerId != null, "Remote peer has not connected yet.", {
873
- F: __dxlog_file3,
1373
+ (0, import_invariant6.invariant)(this._remotePeerId != null, "Remote peer has not connected yet.", {
1374
+ F: __dxlog_file5,
874
1375
  L: 107,
875
1376
  S: this,
876
1377
  A: [
@@ -888,8 +1389,8 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
888
1389
  * Call after the remote peer has connected.
889
1390
  */
890
1391
  enable() {
891
- (0, import_invariant4.invariant)(this._remotePeerId != null, "Remote peer has not connected yet.", {
892
- F: __dxlog_file3,
1392
+ (0, import_invariant6.invariant)(this._remotePeerId != null, "Remote peer has not connected yet.", {
1393
+ F: __dxlog_file5,
893
1394
  L: 120,
894
1395
  S: this,
895
1396
  A: [
@@ -906,7 +1407,7 @@ var MeshReplicatorConnection = class extends import_context4.Resource {
906
1407
  this._isEnabled = false;
907
1408
  }
908
1409
  };
909
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
1410
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
910
1411
  var MeshEchoReplicator = class {
911
1412
  constructor() {
912
1413
  this._connections = /* @__PURE__ */ new Set();
@@ -926,8 +1427,8 @@ var MeshEchoReplicator = class {
926
1427
  this._context = null;
927
1428
  }
928
1429
  createExtension(extensionFactory) {
929
- (0, import_invariant3.invariant)(this._context, void 0, {
930
- F: __dxlog_file4,
1430
+ (0, import_invariant5.invariant)(this._context, void 0, {
1431
+ F: __dxlog_file6,
931
1432
  L: 51,
932
1433
  S: this,
933
1434
  A: [
@@ -939,16 +1440,16 @@ var MeshEchoReplicator = class {
939
1440
  ownPeerId: this._context.peerId,
940
1441
  replicatorFactory: extensionFactory,
941
1442
  onRemoteConnected: async () => {
942
- (0, import_log3.log)("onRemoteConnected", {
1443
+ (0, import_log4.log)("onRemoteConnected", {
943
1444
  peerId: connection.peerId
944
1445
  }, {
945
- F: __dxlog_file4,
1446
+ F: __dxlog_file6,
946
1447
  L: 57,
947
1448
  S: this,
948
1449
  C: (f, a) => f(...a)
949
1450
  });
950
- (0, import_invariant3.invariant)(this._context, void 0, {
951
- F: __dxlog_file4,
1451
+ (0, import_invariant5.invariant)(this._context, void 0, {
1452
+ F: __dxlog_file6,
952
1453
  L: 58,
953
1454
  S: this,
954
1455
  A: [
@@ -965,10 +1466,10 @@ var MeshEchoReplicator = class {
965
1466
  }
966
1467
  },
967
1468
  onRemoteDisconnected: async () => {
968
- (0, import_log3.log)("onRemoteDisconnected", {
1469
+ (0, import_log4.log)("onRemoteDisconnected", {
969
1470
  peerId: connection.peerId
970
1471
  }, {
971
- F: __dxlog_file4,
1472
+ F: __dxlog_file6,
972
1473
  L: 69,
973
1474
  S: this,
974
1475
  C: (f, a) => f(...a)
@@ -979,17 +1480,17 @@ var MeshEchoReplicator = class {
979
1480
  this._connections.delete(connection);
980
1481
  },
981
1482
  shouldAdvertise: async (params) => {
982
- (0, import_log3.log)("shouldAdvertise", {
1483
+ (0, import_log4.log)("shouldAdvertise", {
983
1484
  peerId: connection.peerId,
984
1485
  documentId: params.documentId
985
1486
  }, {
986
- F: __dxlog_file4,
1487
+ F: __dxlog_file6,
987
1488
  L: 76,
988
1489
  S: this,
989
1490
  C: (f, a) => f(...a)
990
1491
  });
991
- (0, import_invariant3.invariant)(this._context, void 0, {
992
- F: __dxlog_file4,
1492
+ (0, import_invariant5.invariant)(this._context, void 0, {
1493
+ F: __dxlog_file6,
993
1494
  L: 77,
994
1495
  S: this,
995
1496
  A: [
@@ -1000,11 +1501,11 @@ var MeshEchoReplicator = class {
1000
1501
  try {
1001
1502
  const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
1002
1503
  if (!spaceKey) {
1003
- (0, import_log3.log)("space key not found for share policy check", {
1504
+ (0, import_log4.log)("space key not found for share policy check", {
1004
1505
  peerId: connection.peerId,
1005
1506
  documentId: params.documentId
1006
1507
  }, {
1007
- F: __dxlog_file4,
1508
+ F: __dxlog_file6,
1008
1509
  L: 81,
1009
1510
  S: this,
1010
1511
  C: (f, a) => f(...a)
@@ -1013,11 +1514,11 @@ var MeshEchoReplicator = class {
1013
1514
  }
1014
1515
  const authorizedDevices = this._authorizedDevices.get(spaceKey);
1015
1516
  if (!connection.remoteDeviceKey) {
1016
- (0, import_log3.log)("device key not found for share policy check", {
1517
+ (0, import_log4.log)("device key not found for share policy check", {
1017
1518
  peerId: connection.peerId,
1018
1519
  documentId: params.documentId
1019
1520
  }, {
1020
- F: __dxlog_file4,
1521
+ F: __dxlog_file6,
1021
1522
  L: 91,
1022
1523
  S: this,
1023
1524
  C: (f, a) => f(...a)
@@ -1025,7 +1526,7 @@ var MeshEchoReplicator = class {
1025
1526
  return false;
1026
1527
  }
1027
1528
  const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
1028
- (0, import_log3.log)("share policy check", {
1529
+ (0, import_log4.log)("share policy check", {
1029
1530
  localPeer: this._context.peerId,
1030
1531
  remotePeer: connection.peerId,
1031
1532
  documentId: params.documentId,
@@ -1033,15 +1534,15 @@ var MeshEchoReplicator = class {
1033
1534
  spaceKey,
1034
1535
  isAuthorized
1035
1536
  }, {
1036
- F: __dxlog_file4,
1537
+ F: __dxlog_file6,
1037
1538
  L: 99,
1038
1539
  S: this,
1039
1540
  C: (f, a) => f(...a)
1040
1541
  });
1041
1542
  return isAuthorized;
1042
1543
  } catch (err) {
1043
- import_log3.log.catch(err, void 0, {
1044
- F: __dxlog_file4,
1544
+ import_log4.log.catch(err, void 0, {
1545
+ F: __dxlog_file6,
1045
1546
  L: 109,
1046
1547
  S: this,
1047
1548
  C: (f, a) => f(...a)
@@ -1054,11 +1555,11 @@ var MeshEchoReplicator = class {
1054
1555
  return connection.replicatorExtension;
1055
1556
  }
1056
1557
  authorizeDevice(spaceKey, deviceKey) {
1057
- (0, import_log3.log)("authorizeDevice", {
1558
+ (0, import_log4.log)("authorizeDevice", {
1058
1559
  spaceKey,
1059
1560
  deviceKey
1060
1561
  }, {
1061
- F: __dxlog_file4,
1562
+ F: __dxlog_file6,
1062
1563
  L: 120,
1063
1564
  S: this,
1064
1565
  C: (f, a) => f(...a)
@@ -1077,12 +1578,14 @@ var MeshEchoReplicator = class {
1077
1578
  0 && (module.exports = {
1078
1579
  AuthExtension,
1079
1580
  AuthStatus,
1581
+ AutomergeDocumentLoaderImpl,
1080
1582
  AutomergeHost,
1081
1583
  CredentialRetrieverExtension,
1082
1584
  CredentialServerExtension,
1083
1585
  DataServiceImpl,
1084
1586
  DocumentsSynchronizer,
1085
1587
  LevelDBStorageAdapter,
1588
+ LocalHostNetworkAdapter,
1086
1589
  MOCK_AUTH_PROVIDER,
1087
1590
  MOCK_AUTH_VERIFIER,
1088
1591
  MeshEchoReplicator,