@dxos/echo-pipeline 0.5.9-main.bdf733d → 0.5.9-main.bf3bb8f

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 (53) hide show
  1. package/dist/lib/browser/{chunk-I2J5TTHJ.mjs → chunk-HS77A4I4.mjs} +174 -23
  2. package/dist/lib/browser/{chunk-I2J5TTHJ.mjs.map → chunk-HS77A4I4.mjs.map} +4 -4
  3. package/dist/lib/browser/index.mjs +272 -299
  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 +11 -7
  7. package/dist/lib/browser/testing/index.mjs.map +1 -1
  8. package/dist/lib/node/{chunk-QPCNQ4ZK.cjs → chunk-Y5U7UXEL.cjs} +185 -34
  9. package/dist/lib/node/{chunk-QPCNQ4ZK.cjs.map → chunk-Y5U7UXEL.cjs.map} +4 -4
  10. package/dist/lib/node/index.cjs +321 -343
  11. package/dist/lib/node/index.cjs.map +4 -4
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +21 -17
  14. package/dist/lib/node/testing/index.cjs.map +1 -1
  15. package/dist/types/src/automerge/automerge-doc-loader.d.ts +2 -1
  16. package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -1
  17. package/dist/types/src/automerge/automerge-host.d.ts +40 -10
  18. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  19. package/dist/types/src/automerge/echo-network-adapter.d.ts +8 -0
  20. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  21. package/dist/types/src/automerge/echo-replicator.d.ts +1 -0
  22. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
  23. package/dist/types/src/automerge/index.d.ts +0 -1
  24. package/dist/types/src/automerge/index.d.ts.map +1 -1
  25. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  26. package/dist/types/src/space/admission-discovery-extension.d.ts +30 -0
  27. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -0
  28. package/dist/types/src/space/index.d.ts +1 -0
  29. package/dist/types/src/space/index.d.ts.map +1 -1
  30. package/dist/types/src/space/space-manager.d.ts +8 -0
  31. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  32. package/package.json +33 -33
  33. package/src/automerge/automerge-doc-loader.test.ts +8 -5
  34. package/src/automerge/automerge-doc-loader.ts +33 -22
  35. package/src/automerge/automerge-host.ts +104 -53
  36. package/src/automerge/echo-network-adapter.ts +30 -8
  37. package/src/automerge/echo-replicator.ts +2 -0
  38. package/src/automerge/index.ts +0 -1
  39. package/src/automerge/mesh-echo-replicator.ts +10 -3
  40. package/src/automerge/storage-adapter.test.ts +103 -139
  41. package/src/space/admission-discovery-extension.ts +90 -0
  42. package/src/space/index.ts +1 -0
  43. package/src/space/space-manager.ts +46 -1
  44. package/src/space/space-protocol.test.ts +2 -0
  45. package/dist/types/src/automerge/automerge-storage-adapter.d.ts +0 -16
  46. package/dist/types/src/automerge/automerge-storage-adapter.d.ts.map +0 -1
  47. package/dist/types/src/automerge/automerge-storage/342/200/223wrapper.d.ts +0 -25
  48. package/dist/types/src/automerge/automerge-storage/342/200/223wrapper.d.ts.map +0 -1
  49. package/dist/types/src/automerge/migrations.d.ts +0 -7
  50. package/dist/types/src/automerge/migrations.d.ts.map +0 -1
  51. package/src/automerge/automerge-storage-adapter.ts +0 -103
  52. package/src/automerge/automerge-storage/342/200/223wrapper.ts +0 -59
  53. package/src/automerge/migrations.ts +0 -42
@@ -3,6 +3,8 @@ import {
3
3
  AuthExtension,
4
4
  AuthStatus,
5
5
  Buffer,
6
+ CredentialRetrieverExtension,
7
+ CredentialServerExtension,
6
8
  DataServiceImpl,
7
9
  MOCK_AUTH_PROVIDER,
8
10
  MOCK_AUTH_VERIFIER,
@@ -23,16 +25,14 @@ import {
23
25
  mapTimeframeToFeedIndexes,
24
26
  startAfter,
25
27
  valueEncoding
26
- } from "./chunk-I2J5TTHJ.mjs";
28
+ } from "./chunk-HS77A4I4.mjs";
27
29
 
28
30
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
29
- import { Event } from "@dxos/async";
30
- import { next as automerge, getBackend, getHeads } from "@dxos/automerge/automerge";
31
+ import { Event, asyncTimeout } from "@dxos/async";
32
+ import { next as automerge, getBackend, getHeads, isAutomerge, save } from "@dxos/automerge/automerge";
31
33
  import { Repo } from "@dxos/automerge/automerge-repo";
32
- import { Context } from "@dxos/context";
33
- import { invariant as invariant3 } from "@dxos/invariant";
34
+ import { Context, cancelWithContext } from "@dxos/context";
34
35
  import { PublicKey } from "@dxos/keys";
35
- import { log as log3 } from "@dxos/log";
36
36
  import { objectPointerCodec } from "@dxos/protocols";
37
37
  import { trace } from "@dxos/tracing";
38
38
  import { mapValues } from "@dxos/util";
@@ -161,13 +161,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
161
161
  peerId: this.peerId,
162
162
  onConnectionOpen: this._onConnectionOpen.bind(this),
163
163
  onConnectionClosed: this._onConnectionClosed.bind(this),
164
+ onConnectionAuthScopeChanged: this._onConnectionAuthScopeChanged.bind(this),
164
165
  getContainingSpaceForDocument: this._params.getContainingSpaceForDocument
165
166
  });
166
167
  }
167
168
  async removeReplicator(replicator) {
168
169
  invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
169
170
  F: __dxlog_file,
170
- L: 102,
171
+ L: 103,
171
172
  S: this,
172
173
  A: [
173
174
  "this._lifecycleState === LifecycleState.OPEN",
@@ -176,14 +177,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
176
177
  });
177
178
  invariant(this._replicators.has(replicator), void 0, {
178
179
  F: __dxlog_file,
179
- L: 103,
180
+ L: 104,
180
181
  S: this,
181
182
  A: [
182
183
  "this._replicators.has(replicator)",
183
184
  ""
184
185
  ]
185
186
  });
186
- "";
187
187
  await replicator.disconnect();
188
188
  this._replicators.delete(replicator);
189
189
  }
@@ -249,27 +249,49 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
249
249
  S: this,
250
250
  C: (f, a) => f(...a)
251
251
  });
252
- this.emit("peer-candidate", {
253
- peerId: connection.peerId,
254
- peerMetadata: {
255
- // TODO(dmaretskyi): Refactor this.
256
- dxos_peerSource: "EchoNetworkAdapter"
257
- }
252
+ this._emitPeerCandidate(connection);
253
+ }
254
+ /**
255
+ * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.
256
+ * TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo
257
+ */
258
+ _onConnectionAuthScopeChanged(connection) {
259
+ log("Connection auth scope changed", {
260
+ peerId: connection.peerId
261
+ }, {
262
+ F: __dxlog_file,
263
+ L: 153,
264
+ S: this,
265
+ C: (f, a) => f(...a)
266
+ });
267
+ const entry = this._connections.get(connection.peerId);
268
+ invariant(entry, void 0, {
269
+ F: __dxlog_file,
270
+ L: 155,
271
+ S: this,
272
+ A: [
273
+ "entry",
274
+ ""
275
+ ]
258
276
  });
277
+ this.emit("peer-disconnected", {
278
+ peerId: connection.peerId
279
+ });
280
+ this._emitPeerCandidate(connection);
259
281
  }
260
282
  _onConnectionClosed(connection) {
261
283
  log("Connection closed", {
262
284
  peerId: connection.peerId
263
285
  }, {
264
286
  F: __dxlog_file,
265
- L: 155,
287
+ L: 161,
266
288
  S: this,
267
289
  C: (f, a) => f(...a)
268
290
  });
269
291
  const entry = this._connections.get(connection.peerId);
270
292
  invariant(entry, void 0, {
271
293
  F: __dxlog_file,
272
- L: 157,
294
+ L: 163,
273
295
  S: this,
274
296
  A: [
275
297
  "entry",
@@ -282,18 +304,24 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
282
304
  });
283
305
  void entry.reader.cancel().catch((err) => log.catch(err, void 0, {
284
306
  F: __dxlog_file,
285
- L: 162,
307
+ L: 168,
286
308
  S: this,
287
309
  C: (f, a) => f(...a)
288
310
  }));
289
311
  void entry.writer.abort().catch((err) => log.catch(err, void 0, {
290
312
  F: __dxlog_file,
291
- L: 163,
313
+ L: 169,
292
314
  S: this,
293
315
  C: (f, a) => f(...a)
294
316
  }));
295
317
  this._connections.delete(connection.peerId);
296
318
  }
319
+ _emitPeerCandidate(connection) {
320
+ this.emit("peer-candidate", {
321
+ peerId: connection.peerId,
322
+ peerMetadata: createEchoPeerMetadata()
323
+ });
324
+ }
297
325
  };
298
326
  _ts_decorate([
299
327
  synchronized
@@ -307,6 +335,11 @@ _ts_decorate([
307
335
  _ts_decorate([
308
336
  synchronized
309
337
  ], EchoNetworkAdapter.prototype, "removeReplicator", null);
338
+ var createEchoPeerMetadata = () => ({
339
+ // TODO(dmaretskyi): Refactor this.
340
+ dxos_peerSource: "EchoNetworkAdapter"
341
+ });
342
+ var isEchoPeerMetadata = (metadata) => metadata?.dxos_peerSource === "EchoNetworkAdapter";
310
343
 
311
344
  // packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
312
345
  import { LifecycleState as LifecycleState2, Resource } from "@dxos/context";
@@ -542,118 +575,6 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter2 {
542
575
  }
543
576
  };
544
577
 
545
- // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
546
- import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
547
- import { log as log2 } from "@dxos/log";
548
- import { StorageType } from "@dxos/random-access-storage";
549
-
550
- // packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
551
- import { arrayToBuffer, bufferToArray } from "@dxos/util";
552
- var AutomergeStorageAdapter = class {
553
- constructor(_directory) {
554
- this._directory = _directory;
555
- this._state = "opened";
556
- }
557
- async load(key) {
558
- if (this._state !== "opened") {
559
- return void 0;
560
- }
561
- const filename = this._getFilename(key);
562
- const file = this._directory.getOrCreateFile(filename);
563
- const { size } = await file.stat();
564
- if (!size || size === 0) {
565
- return void 0;
566
- }
567
- const buffer = await file.read(0, size);
568
- return bufferToArray(buffer);
569
- }
570
- async save(key, data) {
571
- if (this._state !== "opened") {
572
- return void 0;
573
- }
574
- const filename = this._getFilename(key);
575
- const file = this._directory.getOrCreateFile(filename);
576
- await file.write(0, arrayToBuffer(data));
577
- await file.truncate?.(data.length);
578
- await file.flush?.();
579
- }
580
- async remove(key) {
581
- if (this._state !== "opened") {
582
- return void 0;
583
- }
584
- const filename = this._getFilename(key);
585
- const file = this._directory.getOrCreateFile(filename);
586
- await file.destroy();
587
- }
588
- async loadRange(keyPrefix) {
589
- if (this._state !== "opened") {
590
- return [];
591
- }
592
- const filename = this._getFilename(keyPrefix);
593
- const entries = await this._directory.list();
594
- return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
595
- const file = this._directory.getOrCreateFile(entry);
596
- const { size } = await file.stat();
597
- const buffer = await file.read(0, size);
598
- return {
599
- key: this._getKeyFromFilename(entry),
600
- data: bufferToArray(buffer)
601
- };
602
- }));
603
- }
604
- async removeRange(keyPrefix) {
605
- if (this._state !== "opened") {
606
- return void 0;
607
- }
608
- const filename = this._getFilename(keyPrefix);
609
- const entries = await this._directory.list();
610
- await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
611
- const file = this._directory.getOrCreateFile(entry);
612
- await file.destroy();
613
- }));
614
- }
615
- async close() {
616
- this._state = "closed";
617
- }
618
- _getFilename(key) {
619
- return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
620
- }
621
- _getKeyFromFilename(filename) {
622
- return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
623
- }
624
- };
625
-
626
- // packages/core/echo/echo-pipeline/src/automerge/migrations.ts
627
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
628
- var levelMigration = async ({ db, directory }) => {
629
- const isNewLevel = !await db.iterator({
630
- ...encodingOptions
631
- }).next();
632
- if (!isNewLevel) {
633
- return;
634
- }
635
- const oldStorageAdapter = directory.type === StorageType.IDB ? new IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory);
636
- const chunks = await oldStorageAdapter.loadRange([]);
637
- if (chunks.length === 0) {
638
- return;
639
- }
640
- const batch = db.batch();
641
- log2.info("found chunks on old storage adapter", {
642
- chunks: chunks.length
643
- }, {
644
- F: __dxlog_file3,
645
- L: 37,
646
- S: void 0,
647
- C: (f, a) => f(...a)
648
- });
649
- for (const { key, data } of await oldStorageAdapter.loadRange([])) {
650
- data && batch.put(key, data, {
651
- ...encodingOptions
652
- });
653
- }
654
- await batch.write();
655
- };
656
-
657
578
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
658
579
  function _ts_decorate2(decorators, target, key, desc) {
659
580
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -665,31 +586,27 @@ function _ts_decorate2(decorators, target, key, desc) {
665
586
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
666
587
  return c > 3 && r && Object.defineProperty(target, key, r), r;
667
588
  }
668
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
589
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
669
590
  var AutomergeHost = class {
670
- constructor({ directory, db, indexMetadataStore }) {
671
- this._ctx = new Context();
591
+ constructor({ db, indexMetadataStore }) {
592
+ this._ctx = new Context(void 0, {
593
+ F: __dxlog_file3,
594
+ L: 71
595
+ });
672
596
  this._echoNetworkAdapter = new EchoNetworkAdapter({
673
597
  getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this)
674
598
  });
675
- this._requestedDocs = /* @__PURE__ */ new Set();
676
- this._directory = directory;
677
- this._db = db;
678
- this._indexMetadataStore = indexMetadataStore;
679
- }
680
- async open() {
681
- this._peerId = `host-${PublicKey.random().toHex()}`;
682
- this._directory && await levelMigration({
683
- db: this._db,
684
- directory: this._directory
685
- });
686
599
  this._storage = new LevelDBStorageAdapter({
687
- db: this._db,
600
+ db,
688
601
  callbacks: {
689
602
  beforeSave: async (params) => this._beforeSave(params),
690
603
  afterSave: async () => this._afterSave()
691
604
  }
692
605
  });
606
+ this._indexMetadataStore = indexMetadataStore;
607
+ }
608
+ async open() {
609
+ this._peerId = `host-${PublicKey.random().toHex()}`;
693
610
  await this._storage.open?.();
694
611
  this._clientNetwork = new LocalHostNetworkAdapter();
695
612
  this._repo = new Repo({
@@ -714,6 +631,9 @@ var AutomergeHost = class {
714
631
  await this._echoNetworkAdapter.close();
715
632
  await this._ctx.dispose();
716
633
  }
634
+ /**
635
+ * @deprecated To be abstracted away.
636
+ */
717
637
  get repo() {
718
638
  return this._repo;
719
639
  }
@@ -723,6 +643,39 @@ var AutomergeHost = class {
723
643
  async removeReplicator(replicator) {
724
644
  await this._echoNetworkAdapter.removeReplicator(replicator);
725
645
  }
646
+ /**
647
+ * Loads the document handle from the repo and waits for it to be ready.
648
+ */
649
+ async loadDoc(ctx, documentId, opts) {
650
+ let handle;
651
+ if (typeof documentId === "string") {
652
+ handle = this._repo.handles[documentId];
653
+ }
654
+ if (!handle) {
655
+ handle = this._repo.find(documentId);
656
+ }
657
+ if (!handle.isReady()) {
658
+ if (!opts?.timeout) {
659
+ await cancelWithContext(ctx, handle.whenReady());
660
+ } else {
661
+ await cancelWithContext(ctx, asyncTimeout(handle.whenReady(), opts.timeout));
662
+ }
663
+ }
664
+ return handle;
665
+ }
666
+ /**
667
+ * Create new persisted document.
668
+ */
669
+ createDoc(initialValue, opts) {
670
+ if (opts?.preserveHistory) {
671
+ if (!isAutomerge(initialValue)) {
672
+ throw new TypeError("Initial value must be an Automerge document");
673
+ }
674
+ return this._repo.import(save(initialValue));
675
+ } else {
676
+ return this._repo.create(initialValue);
677
+ }
678
+ }
726
679
  // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
727
680
  // Hosts, running in the worker, don't share documents unless requested by other peers.
728
681
  // NOTE: If both peers return sharePolicy=false the replication will not happen
@@ -734,23 +687,8 @@ var AutomergeHost = class {
734
687
  if (!documentId) {
735
688
  return false;
736
689
  }
737
- const doc = this._repo.handles[documentId]?.docSync();
738
- if (!doc) {
739
- const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
740
- log3("doc share policy check", {
741
- peerId,
742
- documentId,
743
- isRequested
744
- }, {
745
- F: __dxlog_file4,
746
- L: 156,
747
- S: this,
748
- C: (f, a) => f(...a)
749
- });
750
- return isRequested;
751
- }
752
690
  const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
753
- if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
691
+ if (isEchoPeerMetadata(peerMetadata)) {
754
692
  return this._echoNetworkAdapter.shouldAdvertize(peerId, {
755
693
  documentId
756
694
  });
@@ -822,31 +760,36 @@ var AutomergeHost = class {
822
760
  }
823
761
  return PublicKey.from(spaceKeyHex);
824
762
  }
825
- //
826
- // Methods for client-services.
827
- //
763
+ /**
764
+ * Flush documents to disk.
765
+ */
828
766
  async flush({ states }) {
829
- await Promise.all(states?.map(async ({ heads, documentId }) => {
830
- invariant3(heads, "heads are required for flush", {
831
- F: __dxlog_file4,
832
- L: 250,
833
- S: this,
834
- A: [
835
- "heads",
836
- "'heads are required for flush'"
837
- ]
838
- });
839
- const handle = this.repo.handles[documentId] ?? this._repo.find(documentId);
840
- await waitForHeads(handle, heads);
841
- }) ?? []);
767
+ if (states) {
768
+ await Promise.all(states.map(async ({ heads, documentId }) => {
769
+ if (!heads) {
770
+ return;
771
+ }
772
+ const handle = this.repo.handles[documentId] ?? this._repo.find(documentId);
773
+ await waitForHeads(handle, heads);
774
+ }) ?? []);
775
+ }
842
776
  await this._repo.flush(states?.map(({ documentId }) => documentId));
843
777
  }
778
+ /**
779
+ * Host <-> Client sync.
780
+ */
844
781
  syncRepo(request) {
845
782
  return this._clientNetwork.syncRepo(request);
846
783
  }
784
+ /**
785
+ * Host <-> Client sync.
786
+ */
847
787
  sendSyncMessage(request) {
848
788
  return this._clientNetwork.sendSyncMessage(request);
849
789
  }
790
+ /**
791
+ * Host <-> Client sync.
792
+ */
850
793
  async getHostInfo() {
851
794
  return this._clientNetwork.getHostInfo();
852
795
  }
@@ -900,10 +843,12 @@ var changeIsPresentInDoc = (doc, changeHash) => {
900
843
 
901
844
  // packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts
902
845
  import { Event as Event2 } from "@dxos/async";
903
- import { cancelWithContext } from "@dxos/context";
846
+ import { interpretAsDocumentId } from "@dxos/automerge/automerge-repo";
847
+ import { cancelWithContext as cancelWithContext2 } from "@dxos/context";
904
848
  import { warnAfterTimeout } from "@dxos/debug";
905
- import { invariant as invariant4 } from "@dxos/invariant";
906
- import { log as log4 } from "@dxos/log";
849
+ import { SpaceDocVersion } from "@dxos/echo-protocol";
850
+ import { invariant as invariant3 } from "@dxos/invariant";
851
+ import { log as log2 } from "@dxos/log";
907
852
  import { trace as trace2 } from "@dxos/tracing";
908
853
  function _ts_decorate3(decorators, target, key, desc) {
909
854
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -915,7 +860,7 @@ function _ts_decorate3(decorators, target, key, desc) {
915
860
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
916
861
  return c > 3 && r && Object.defineProperty(target, key, r), r;
917
862
  }
918
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
863
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
919
864
  var AutomergeDocumentLoaderImpl = class {
920
865
  constructor(_spaceId, _repo, _spaceKey) {
921
866
  this._spaceId = _spaceId;
@@ -937,32 +882,32 @@ var AutomergeDocumentLoaderImpl = class {
937
882
  return;
938
883
  }
939
884
  if (!spaceState.rootUrl) {
940
- log4.error("Database opened with no rootUrl", {
941
- spaceId: this._spaceId
942
- }, {
943
- F: __dxlog_file5,
944
- L: 72,
945
- S: this,
946
- C: (f, a) => f(...a)
947
- });
948
- this._createContextBoundSpaceRootDocument(ctx);
949
- } else {
950
- const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
951
- const doc = existingDocHandle.docSync();
952
- invariant4(doc, void 0, {
953
- F: __dxlog_file5,
954
- L: 77,
955
- S: this,
956
- A: [
957
- "doc",
958
- ""
959
- ]
960
- });
961
- if (doc.access == null) {
962
- this._initDocAccess(existingDocHandle);
963
- }
964
- this._spaceRootDocHandle = existingDocHandle;
885
+ throw new Error("Database opened with no rootUrl");
965
886
  }
887
+ const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
888
+ const doc = existingDocHandle.docSync();
889
+ invariant3(doc, void 0, {
890
+ F: __dxlog_file4,
891
+ L: 84,
892
+ S: this,
893
+ A: [
894
+ "doc",
895
+ ""
896
+ ]
897
+ });
898
+ invariant3(doc.version === SpaceDocVersion.CURRENT, void 0, {
899
+ F: __dxlog_file4,
900
+ L: 85,
901
+ S: this,
902
+ A: [
903
+ "doc.version === SpaceDocVersion.CURRENT",
904
+ ""
905
+ ]
906
+ });
907
+ if (doc.access == null) {
908
+ this._initDocAccess(existingDocHandle);
909
+ }
910
+ this._spaceRootDocHandle = existingDocHandle;
966
911
  }
967
912
  loadObjectDocument(objectIdOrMany) {
968
913
  const objectIds = Array.isArray(objectIdOrMany) ? objectIdOrMany : [
@@ -971,9 +916,9 @@ var AutomergeDocumentLoaderImpl = class {
971
916
  let hasUrlsToLoad = false;
972
917
  const urlsToLoad = {};
973
918
  for (const objectId of objectIds) {
974
- invariant4(this._spaceRootDocHandle, void 0, {
975
- F: __dxlog_file5,
976
- L: 90,
919
+ invariant3(this._spaceRootDocHandle, void 0, {
920
+ F: __dxlog_file4,
921
+ L: 97,
977
922
  S: this,
978
923
  A: [
979
924
  "this._spaceRootDocHandle",
@@ -984,9 +929,9 @@ var AutomergeDocumentLoaderImpl = class {
984
929
  continue;
985
930
  }
986
931
  const spaceRootDoc = this._spaceRootDocHandle.docSync();
987
- invariant4(spaceRootDoc, void 0, {
988
- F: __dxlog_file5,
989
- L: 95,
932
+ invariant3(spaceRootDoc, void 0, {
933
+ F: __dxlog_file4,
934
+ L: 102,
990
935
  S: this,
991
936
  A: [
992
937
  "spaceRootDoc",
@@ -996,11 +941,11 @@ var AutomergeDocumentLoaderImpl = class {
996
941
  const documentUrl = (spaceRootDoc.links ?? {})[objectId];
997
942
  if (documentUrl == null) {
998
943
  this._objectsPendingDocumentLoad.add(objectId);
999
- log4.info("loading delayed until object links are initialized", {
944
+ log2.info("loading delayed until object links are initialized", {
1000
945
  objectId
1001
946
  }, {
1002
- F: __dxlog_file5,
1003
- L: 99,
947
+ F: __dxlog_file4,
948
+ L: 106,
1004
949
  S: this,
1005
950
  C: (f, a) => f(...a)
1006
951
  });
@@ -1013,6 +958,32 @@ var AutomergeDocumentLoaderImpl = class {
1013
958
  this._loadLinkedObjects(urlsToLoad);
1014
959
  }
1015
960
  }
961
+ getObjectDocumentId(objectId) {
962
+ invariant3(this._spaceRootDocHandle, void 0, {
963
+ F: __dxlog_file4,
964
+ L: 118,
965
+ S: this,
966
+ A: [
967
+ "this._spaceRootDocHandle",
968
+ ""
969
+ ]
970
+ });
971
+ const spaceRootDoc = this._spaceRootDocHandle.docSync();
972
+ invariant3(spaceRootDoc, void 0, {
973
+ F: __dxlog_file4,
974
+ L: 120,
975
+ S: this,
976
+ A: [
977
+ "spaceRootDoc",
978
+ ""
979
+ ]
980
+ });
981
+ if (spaceRootDoc.objects?.[objectId]) {
982
+ return this._spaceRootDocHandle.documentId;
983
+ }
984
+ const documentUrl = (spaceRootDoc.links ?? {})[objectId];
985
+ return documentUrl && interpretAsDocumentId(documentUrl);
986
+ }
1016
987
  onObjectLinksUpdated(links) {
1017
988
  if (!links) {
1018
989
  return;
@@ -1022,9 +993,9 @@ var AutomergeDocumentLoaderImpl = class {
1022
993
  linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
1023
994
  }
1024
995
  getSpaceRootDocHandle() {
1025
- invariant4(this._spaceRootDocHandle, void 0, {
1026
- F: __dxlog_file5,
1027
- L: 122,
996
+ invariant3(this._spaceRootDocHandle, void 0, {
997
+ F: __dxlog_file4,
998
+ L: 140,
1028
999
  S: this,
1029
1000
  A: [
1030
1001
  "this._spaceRootDocHandle",
@@ -1034,16 +1005,18 @@ var AutomergeDocumentLoaderImpl = class {
1034
1005
  return this._spaceRootDocHandle;
1035
1006
  }
1036
1007
  createDocumentForObject(objectId) {
1037
- invariant4(this._spaceRootDocHandle, void 0, {
1038
- F: __dxlog_file5,
1039
- L: 127,
1008
+ invariant3(this._spaceRootDocHandle, void 0, {
1009
+ F: __dxlog_file4,
1010
+ L: 145,
1040
1011
  S: this,
1041
1012
  A: [
1042
1013
  "this._spaceRootDocHandle",
1043
1014
  ""
1044
1015
  ]
1045
1016
  });
1046
- const spaceDocHandle = this._repo.create();
1017
+ const spaceDocHandle = this._repo.create({
1018
+ version: SpaceDocVersion.CURRENT
1019
+ });
1047
1020
  this._initDocAccess(spaceDocHandle);
1048
1021
  this.onObjectBoundToDocument(spaceDocHandle, objectId);
1049
1022
  this._spaceRootDocHandle.change((newDoc) => {
@@ -1074,30 +1047,30 @@ var AutomergeDocumentLoaderImpl = class {
1074
1047
  };
1075
1048
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
1076
1049
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
1077
- log4.warn("object already inlined in a different document, ignoring the link", {
1050
+ log2.warn("object already inlined in a different document, ignoring the link", {
1078
1051
  ...logMeta,
1079
1052
  actualDocumentUrl: objectDocumentHandle.url
1080
1053
  }, {
1081
- F: __dxlog_file5,
1082
- L: 157,
1054
+ F: __dxlog_file4,
1055
+ L: 177,
1083
1056
  S: this,
1084
1057
  C: (f, a) => f(...a)
1085
1058
  });
1086
1059
  continue;
1087
1060
  }
1088
1061
  if (objectDocumentHandle?.url === automergeUrl) {
1089
- log4.warn("object document was already loaded", logMeta, {
1090
- F: __dxlog_file5,
1091
- L: 164,
1062
+ log2.warn("object document was already loaded", logMeta, {
1063
+ F: __dxlog_file4,
1064
+ L: 184,
1092
1065
  S: this,
1093
1066
  C: (f, a) => f(...a)
1094
1067
  });
1095
1068
  continue;
1096
1069
  }
1097
1070
  const handle = this._repo.find(automergeUrl);
1098
- log4.debug("document loading triggered", logMeta, {
1099
- F: __dxlog_file5,
1100
- L: 168,
1071
+ log2.debug("document loading triggered", logMeta, {
1072
+ F: __dxlog_file4,
1073
+ L: 188,
1101
1074
  S: this,
1102
1075
  C: (f, a) => f(...a)
1103
1076
  });
@@ -1110,17 +1083,17 @@ var AutomergeDocumentLoaderImpl = class {
1110
1083
  while (true) {
1111
1084
  try {
1112
1085
  await warnAfterTimeout(5e3, "Automerge root doc load timeout (CoreDatabase)", async () => {
1113
- await cancelWithContext(ctx, docHandle.whenReady());
1086
+ await cancelWithContext2(ctx, docHandle.whenReady());
1114
1087
  });
1115
1088
  break;
1116
1089
  } catch (err) {
1117
1090
  if (`${err}`.includes("Timeout")) {
1118
- log4.info("wraparound", {
1091
+ log2.info("wraparound", {
1119
1092
  id: docHandle.documentId,
1120
1093
  state: docHandle.state
1121
1094
  }, {
1122
- F: __dxlog_file5,
1123
- L: 184,
1095
+ F: __dxlog_file4,
1096
+ L: 204,
1124
1097
  S: this,
1125
1098
  C: (f, a) => f(...a)
1126
1099
  });
@@ -1134,14 +1107,6 @@ var AutomergeDocumentLoaderImpl = class {
1134
1107
  }
1135
1108
  return docHandle;
1136
1109
  }
1137
- _createContextBoundSpaceRootDocument(ctx) {
1138
- const docHandle = this._repo.create();
1139
- this._spaceRootDocHandle = docHandle;
1140
- ctx.onDispose(() => {
1141
- docHandle.delete();
1142
- this._spaceRootDocHandle = null;
1143
- });
1144
- }
1145
1110
  _initDocAccess(handle) {
1146
1111
  handle.change((newDoc) => {
1147
1112
  newDoc.access ??= {
@@ -1160,9 +1125,9 @@ var AutomergeDocumentLoaderImpl = class {
1160
1125
  docUrl: handle.url
1161
1126
  };
1162
1127
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
1163
- log4.info("document loaded after all listeners were removed", logMeta, {
1164
- F: __dxlog_file5,
1165
- L: 220,
1128
+ log2.info("document loaded after all listeners were removed", logMeta, {
1129
+ F: __dxlog_file4,
1130
+ L: 231,
1166
1131
  S: this,
1167
1132
  C: (f, a) => f(...a)
1168
1133
  });
@@ -1170,9 +1135,9 @@ var AutomergeDocumentLoaderImpl = class {
1170
1135
  }
1171
1136
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
1172
1137
  if (objectDocHandle?.url !== handle.url) {
1173
- log4.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1174
- F: __dxlog_file5,
1175
- L: 225,
1138
+ log2.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1139
+ F: __dxlog_file4,
1140
+ L: 236,
1176
1141
  S: this,
1177
1142
  C: (f, a) => f(...a)
1178
1143
  });
@@ -1184,14 +1149,14 @@ var AutomergeDocumentLoaderImpl = class {
1184
1149
  });
1185
1150
  } catch (err) {
1186
1151
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1187
- log4.warn("failed to load a document", {
1152
+ log2.warn("failed to load a document", {
1188
1153
  objectId,
1189
1154
  automergeUrl: handle.url,
1190
1155
  retryLoading: shouldRetryLoading,
1191
1156
  err
1192
1157
  }, {
1193
- F: __dxlog_file5,
1194
- L: 231,
1158
+ F: __dxlog_file4,
1159
+ L: 242,
1195
1160
  S: this,
1196
1161
  C: (f, a) => f(...a)
1197
1162
  });
@@ -1213,12 +1178,12 @@ AutomergeDocumentLoaderImpl = _ts_decorate3([
1213
1178
  // packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
1214
1179
  import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
1215
1180
  import { Resource as Resource2 } from "@dxos/context";
1216
- import { invariant as invariant5 } from "@dxos/invariant";
1181
+ import { invariant as invariant4 } from "@dxos/invariant";
1217
1182
  import { PublicKey as PublicKey2 } from "@dxos/keys";
1218
- import { log as log5 } from "@dxos/log";
1183
+ import { log as log3 } from "@dxos/log";
1219
1184
  import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
1220
1185
  import { ComplexMap, ComplexSet, defaultMap } from "@dxos/util";
1221
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
1186
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
1222
1187
  var MeshEchoReplicator = class {
1223
1188
  constructor() {
1224
1189
  this._connections = /* @__PURE__ */ new Set();
@@ -1244,8 +1209,8 @@ var MeshEchoReplicator = class {
1244
1209
  this._context = null;
1245
1210
  }
1246
1211
  createExtension() {
1247
- invariant5(this._context, void 0, {
1248
- F: __dxlog_file6,
1212
+ invariant4(this._context, void 0, {
1213
+ F: __dxlog_file5,
1249
1214
  L: 54,
1250
1215
  S: this,
1251
1216
  A: [
@@ -1256,16 +1221,16 @@ var MeshEchoReplicator = class {
1256
1221
  const connection = new MeshReplicatorConnection({
1257
1222
  ownPeerId: this._context.peerId,
1258
1223
  onRemoteConnected: async () => {
1259
- log5("onRemoteConnected", {
1224
+ log3("onRemoteConnected", {
1260
1225
  peerId: connection.peerId
1261
1226
  }, {
1262
- F: __dxlog_file6,
1227
+ F: __dxlog_file5,
1263
1228
  L: 59,
1264
1229
  S: this,
1265
1230
  C: (f, a) => f(...a)
1266
1231
  });
1267
- invariant5(this._context, void 0, {
1268
- F: __dxlog_file6,
1232
+ invariant4(this._context, void 0, {
1233
+ F: __dxlog_file5,
1269
1234
  L: 60,
1270
1235
  S: this,
1271
1236
  A: [
@@ -1273,39 +1238,41 @@ var MeshEchoReplicator = class {
1273
1238
  ""
1274
1239
  ]
1275
1240
  });
1276
- if (!this._connectionsPerPeer.has(connection.peerId)) {
1241
+ if (this._connectionsPerPeer.has(connection.peerId)) {
1242
+ this._context.onConnectionAuthScopeChanged(connection);
1243
+ } else {
1277
1244
  this._connectionsPerPeer.set(connection.peerId, connection);
1278
- await connection.enable();
1279
1245
  this._context.onConnectionOpen(connection);
1246
+ await connection.enable();
1280
1247
  }
1281
1248
  },
1282
1249
  onRemoteDisconnected: async () => {
1283
- log5("onRemoteDisconnected", {
1250
+ log3("onRemoteDisconnected", {
1284
1251
  peerId: connection.peerId
1285
1252
  }, {
1286
- F: __dxlog_file6,
1287
- L: 69,
1253
+ F: __dxlog_file5,
1254
+ L: 71,
1288
1255
  S: this,
1289
1256
  C: (f, a) => f(...a)
1290
1257
  });
1291
1258
  this._context?.onConnectionClosed(connection);
1292
- await connection.disable();
1293
1259
  this._connectionsPerPeer.delete(connection.peerId);
1260
+ await connection.disable();
1294
1261
  this._connections.delete(connection);
1295
1262
  },
1296
1263
  shouldAdvertize: async (params) => {
1297
- log5("shouldAdvertize", {
1264
+ log3("shouldAdvertize", {
1298
1265
  peerId: connection.peerId,
1299
1266
  documentId: params.documentId
1300
1267
  }, {
1301
- F: __dxlog_file6,
1302
- L: 76,
1268
+ F: __dxlog_file5,
1269
+ L: 78,
1303
1270
  S: this,
1304
1271
  C: (f, a) => f(...a)
1305
1272
  });
1306
- invariant5(this._context, void 0, {
1307
- F: __dxlog_file6,
1308
- L: 77,
1273
+ invariant4(this._context, void 0, {
1274
+ F: __dxlog_file5,
1275
+ L: 79,
1309
1276
  S: this,
1310
1277
  A: [
1311
1278
  "this._context",
@@ -1315,12 +1282,12 @@ var MeshEchoReplicator = class {
1315
1282
  try {
1316
1283
  const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
1317
1284
  if (!spaceKey) {
1318
- log5("space key not found for share policy check", {
1285
+ log3("space key not found for share policy check", {
1319
1286
  peerId: connection.peerId,
1320
1287
  documentId: params.documentId
1321
1288
  }, {
1322
- F: __dxlog_file6,
1323
- L: 81,
1289
+ F: __dxlog_file5,
1290
+ L: 83,
1324
1291
  S: this,
1325
1292
  C: (f, a) => f(...a)
1326
1293
  });
@@ -1328,19 +1295,19 @@ var MeshEchoReplicator = class {
1328
1295
  }
1329
1296
  const authorizedDevices = this._authorizedDevices.get(spaceKey);
1330
1297
  if (!connection.remoteDeviceKey) {
1331
- log5("device key not found for share policy check", {
1298
+ log3("device key not found for share policy check", {
1332
1299
  peerId: connection.peerId,
1333
1300
  documentId: params.documentId
1334
1301
  }, {
1335
- F: __dxlog_file6,
1336
- L: 91,
1302
+ F: __dxlog_file5,
1303
+ L: 93,
1337
1304
  S: this,
1338
1305
  C: (f, a) => f(...a)
1339
1306
  });
1340
1307
  return false;
1341
1308
  }
1342
1309
  const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
1343
- log5("share policy check", {
1310
+ log3("share policy check", {
1344
1311
  localPeer: this._context.peerId,
1345
1312
  remotePeer: connection.peerId,
1346
1313
  documentId: params.documentId,
@@ -1348,16 +1315,16 @@ var MeshEchoReplicator = class {
1348
1315
  spaceKey,
1349
1316
  isAuthorized
1350
1317
  }, {
1351
- F: __dxlog_file6,
1352
- L: 99,
1318
+ F: __dxlog_file5,
1319
+ L: 101,
1353
1320
  S: this,
1354
1321
  C: (f, a) => f(...a)
1355
1322
  });
1356
1323
  return isAuthorized;
1357
1324
  } catch (err) {
1358
- log5.catch(err, void 0, {
1359
- F: __dxlog_file6,
1360
- L: 109,
1325
+ log3.catch(err, void 0, {
1326
+ F: __dxlog_file5,
1327
+ L: 111,
1361
1328
  S: this,
1362
1329
  C: (f, a) => f(...a)
1363
1330
  });
@@ -1369,16 +1336,21 @@ var MeshEchoReplicator = class {
1369
1336
  return connection.replicatorExtension;
1370
1337
  }
1371
1338
  authorizeDevice(spaceKey, deviceKey) {
1372
- log5("authorizeDevice", {
1339
+ log3("authorizeDevice", {
1373
1340
  spaceKey,
1374
1341
  deviceKey
1375
1342
  }, {
1376
- F: __dxlog_file6,
1377
- L: 120,
1343
+ F: __dxlog_file5,
1344
+ L: 122,
1378
1345
  S: this,
1379
1346
  C: (f, a) => f(...a)
1380
1347
  });
1381
1348
  defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey2.hash)).add(deviceKey);
1349
+ for (const connection of this._connections) {
1350
+ if (connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
1351
+ this._context?.onConnectionAuthScopeChanged(connection);
1352
+ }
1353
+ }
1382
1354
  }
1383
1355
  };
1384
1356
  var MeshReplicatorConnection = class extends Resource2 {
@@ -1410,13 +1382,13 @@ var MeshReplicatorConnection = class extends Resource2 {
1410
1382
  onStartReplication: async (info, remotePeerId) => {
1411
1383
  this.remoteDeviceKey = remotePeerId;
1412
1384
  this._remotePeerId = info.id;
1413
- log5("onStartReplication", {
1385
+ log3("onStartReplication", {
1414
1386
  id: info.id,
1415
1387
  thisPeerId: this.peerId,
1416
1388
  remotePeerId: remotePeerId.toHex()
1417
1389
  }, {
1418
- F: __dxlog_file6,
1419
- L: 185,
1390
+ F: __dxlog_file5,
1391
+ L: 192,
1420
1392
  S: this,
1421
1393
  C: (f, a) => f(...a)
1422
1394
  });
@@ -1438,9 +1410,9 @@ var MeshReplicatorConnection = class extends Resource2 {
1438
1410
  });
1439
1411
  }
1440
1412
  get peerId() {
1441
- invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1442
- F: __dxlog_file6,
1443
- L: 208,
1413
+ invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
1414
+ F: __dxlog_file5,
1415
+ L: 215,
1444
1416
  S: this,
1445
1417
  A: [
1446
1418
  "this._remotePeerId != null",
@@ -1457,9 +1429,9 @@ var MeshReplicatorConnection = class extends Resource2 {
1457
1429
  * Call after the remote peer has connected.
1458
1430
  */
1459
1431
  async enable() {
1460
- invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
1461
- F: __dxlog_file6,
1462
- L: 221,
1432
+ invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
1433
+ F: __dxlog_file5,
1434
+ L: 228,
1463
1435
  S: this,
1464
1436
  A: [
1465
1437
  "this._remotePeerId != null",
@@ -1480,7 +1452,8 @@ export {
1480
1452
  AuthStatus,
1481
1453
  AutomergeDocumentLoaderImpl,
1482
1454
  AutomergeHost,
1483
- AutomergeStorageAdapter,
1455
+ CredentialRetrieverExtension,
1456
+ CredentialServerExtension,
1484
1457
  DataServiceImpl,
1485
1458
  LevelDBStorageAdapter,
1486
1459
  LocalHostNetworkAdapter,