@dxos/echo-pipeline 0.4.10-main.e17362e → 0.4.10-main.e96274c

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 (34) hide show
  1. package/dist/lib/browser/index.mjs +58 -104
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs.map +1 -1
  5. package/dist/lib/node/index.cjs +68 -112
  6. package/dist/lib/node/index.cjs.map +3 -3
  7. package/dist/lib/node/meta.json +1 -1
  8. package/dist/lib/node/testing/index.cjs.map +1 -1
  9. package/dist/types/src/automerge/automerge-host.d.ts +6 -13
  10. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  11. package/dist/types/src/automerge/automerge-repo.test.d.ts +2 -0
  12. package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -0
  13. package/dist/types/src/automerge/index.d.ts +1 -0
  14. package/dist/types/src/automerge/index.d.ts.map +1 -1
  15. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +11 -8
  16. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  17. package/dist/types/src/automerge/migrations.d.ts +2 -2
  18. package/dist/types/src/automerge/reference.d.ts +1 -1
  19. package/dist/types/src/automerge/reference.d.ts.map +1 -1
  20. package/dist/types/src/automerge/types.d.ts +4 -3
  21. package/dist/types/src/automerge/types.d.ts.map +1 -1
  22. package/dist/types/src/testing/level.d.ts +2 -2
  23. package/package.json +30 -30
  24. package/src/automerge/automerge-host.test.ts +4 -4
  25. package/src/automerge/automerge-host.ts +28 -101
  26. package/src/automerge/automerge-repo.test.ts +29 -0
  27. package/src/automerge/index.ts +1 -0
  28. package/src/automerge/level.test.ts +23 -2
  29. package/src/automerge/leveldb-storage-adapter.ts +36 -24
  30. package/src/automerge/migrations.ts +2 -2
  31. package/src/automerge/reference.ts +1 -1
  32. package/src/automerge/storage-adapter.test.ts +4 -4
  33. package/src/automerge/types.ts +4 -3
  34. package/src/testing/level.ts +2 -2
@@ -25,41 +25,54 @@ import {
25
25
  } from "./chunk-SYE4EK33.mjs";
26
26
 
27
27
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
28
- import { next as automerge, getHeads } from "@dxos/automerge/automerge";
28
+ import { asyncTimeout } from "@dxos/async";
29
+ import { next as automerge } from "@dxos/automerge/automerge";
29
30
  import { Repo } from "@dxos/automerge/automerge-repo";
30
31
  import { Context } from "@dxos/context";
31
32
  import { PublicKey } from "@dxos/keys";
32
33
  import { log as log3 } from "@dxos/log";
33
- import { idCodec } from "@dxos/protocols";
34
34
  import { trace } from "@dxos/tracing";
35
35
  import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
36
36
 
37
37
  // packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
38
- var LevelDBStorageAdapter = class {
38
+ import { LifecycleState, Resource } from "@dxos/context";
39
+ var LevelDBStorageAdapter = class extends Resource {
39
40
  constructor(_params) {
41
+ super();
40
42
  this._params = _params;
41
- this._state = "opened";
42
43
  }
43
44
  async load(keyArray) {
44
- if (this._state !== "opened") {
45
- return void 0;
45
+ try {
46
+ if (this._lifecycleState !== LifecycleState.OPEN) {
47
+ return void 0;
48
+ }
49
+ return await this._params.db.get(keyArray, {
50
+ ...encodingOptions
51
+ });
52
+ } catch (err) {
53
+ if (isLevelDbNotFoundError(err)) {
54
+ return void 0;
55
+ }
56
+ throw err;
46
57
  }
47
- return this._params.db.get(keyArray, {
48
- ...encodingOptions
49
- }).catch((err) => err.code === "LEVEL_NOT_FOUND" ? void 0 : Promise.reject(err));
50
58
  }
51
59
  async save(keyArray, binary) {
52
- if (this._state !== "opened") {
60
+ if (this._lifecycleState !== LifecycleState.OPEN) {
53
61
  return void 0;
54
62
  }
55
- await this._params.callbacks?.beforeSave?.(keyArray);
56
- await this._params.db.put(keyArray, Buffer.from(binary), {
63
+ const batch = this._params.db.batch();
64
+ await this._params.callbacks?.beforeSave?.({
65
+ path: keyArray,
66
+ batch
67
+ });
68
+ batch.put(keyArray, Buffer.from(binary), {
57
69
  ...encodingOptions
58
70
  });
71
+ await batch.write();
59
72
  await this._params.callbacks?.afterSave?.(keyArray);
60
73
  }
61
74
  async remove(keyArray) {
62
- if (this._state !== "opened") {
75
+ if (this._lifecycleState !== LifecycleState.OPEN) {
63
76
  return void 0;
64
77
  }
65
78
  await this._params.db.del(keyArray, {
@@ -67,7 +80,7 @@ var LevelDBStorageAdapter = class {
67
80
  });
68
81
  }
69
82
  async loadRange(keyPrefix) {
70
- if (this._state !== "opened") {
83
+ if (this._lifecycleState !== LifecycleState.OPEN) {
71
84
  return [];
72
85
  }
73
86
  const result = [];
@@ -87,7 +100,7 @@ var LevelDBStorageAdapter = class {
87
100
  return result;
88
101
  }
89
102
  async removeRange(keyPrefix) {
90
- if (this._state !== "opened") {
103
+ if (this._lifecycleState !== LifecycleState.OPEN) {
91
104
  return void 0;
92
105
  }
93
106
  const batch = this._params.db.batch();
@@ -105,9 +118,6 @@ var LevelDBStorageAdapter = class {
105
118
  }
106
119
  await batch.write();
107
120
  }
108
- close() {
109
- this._state = "closed";
110
- }
111
121
  };
112
122
  var keyEncoder = {
113
123
  encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
@@ -117,6 +127,7 @@ var encodingOptions = {
117
127
  keyEncoding: keyEncoder,
118
128
  valueEncoding: "buffer"
119
129
  };
130
+ var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
120
131
 
121
132
  // packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
122
133
  import { Trigger } from "@dxos/async";
@@ -498,29 +509,27 @@ function _ts_decorate(decorators, target, key, desc) {
498
509
  }
499
510
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
500
511
  var AutomergeHost = class {
501
- constructor({ directory, db, metadata }) {
512
+ constructor({ directory, db, storageCallbacks }) {
502
513
  this._ctx = new Context();
503
514
  /**
504
515
  * spaceKey -> deviceKey[]
505
516
  */
506
517
  this._authorizedDevices = new ComplexMap(PublicKey.hash);
507
- this._updatingMetadata = /* @__PURE__ */ new Map();
508
518
  this._requestedDocs = /* @__PURE__ */ new Set();
509
519
  this._directory = directory;
510
520
  this._db = db;
511
- this._metadata = metadata;
521
+ this._storageCallbacks = storageCallbacks;
512
522
  }
513
523
  async open() {
514
524
  this._directory && await levelMigration({
515
- db: await this._db,
525
+ db: this._db,
516
526
  directory: this._directory
517
527
  });
518
528
  this._storage = new LevelDBStorageAdapter({
519
- db: await this._db,
520
- callbacks: {
521
- beforeSave: (params) => this._beforeSave(params)
522
- }
529
+ db: this._db,
530
+ callbacks: this._storageCallbacks
523
531
  });
532
+ await this._storage.open?.();
524
533
  this._peerId = `host-${PublicKey.random().toHex()}`;
525
534
  this._meshNetwork = new MeshNetworkAdapter();
526
535
  this._clientNetwork = new LocalHostNetworkAdapter();
@@ -549,7 +558,7 @@ var AutomergeHost = class {
549
558
  isRequested
550
559
  }, {
551
560
  F: __dxlog_file4,
552
- L: 111,
561
+ L: 100,
553
562
  S: this,
554
563
  C: (f, a) => f(...a)
555
564
  });
@@ -563,7 +572,7 @@ var AutomergeHost = class {
563
572
  documentId
564
573
  }, {
565
574
  F: __dxlog_file4,
566
- L: 118,
575
+ L: 107,
567
576
  S: this,
568
577
  C: (f, a) => f(...a)
569
578
  });
@@ -577,7 +586,7 @@ var AutomergeHost = class {
577
586
  documentId
578
587
  }, {
579
588
  F: __dxlog_file4,
580
- L: 127,
589
+ L: 116,
581
590
  S: this,
582
591
  C: (f, a) => f(...a)
583
592
  });
@@ -594,7 +603,7 @@ var AutomergeHost = class {
594
603
  isAuthorized
595
604
  }, {
596
605
  F: __dxlog_file4,
597
- L: 133,
606
+ L: 122,
598
607
  S: this,
599
608
  C: (f, a) => f(...a)
600
609
  });
@@ -602,7 +611,7 @@ var AutomergeHost = class {
602
611
  } catch (err) {
603
612
  log3.catch(err, void 0, {
604
613
  F: __dxlog_file4,
605
- L: 143,
614
+ L: 132,
606
615
  S: this,
607
616
  C: (f, a) => f(...a)
608
617
  });
@@ -612,67 +621,16 @@ var AutomergeHost = class {
612
621
  });
613
622
  this._clientNetwork.ready();
614
623
  this._meshNetwork.ready();
615
- {
616
- const listener = ({ handle }) => this._onDocument(handle);
617
- this._repo.on("document", listener);
618
- this._ctx.onDispose(() => {
619
- this._repo.off("document", listener);
620
- Object.values(this._repo.handles).forEach((handle) => handle.off("change"));
621
- });
622
- }
623
624
  await this._clientNetwork.whenConnected();
624
625
  }
625
626
  async close() {
626
- this._storage.close?.();
627
+ await this._storage.close?.();
627
628
  await this._clientNetwork.close();
628
629
  await this._ctx.dispose();
629
630
  }
630
631
  get repo() {
631
632
  return this._repo;
632
633
  }
633
- async _beforeSave(path) {
634
- const id = path[0];
635
- if (this._updatingMetadata.has(id)) {
636
- return this._updatingMetadata.get(id);
637
- }
638
- }
639
- _onDocument(handle) {
640
- const listener = (event) => this._onUpdate(event);
641
- handle.on("change", listener);
642
- }
643
- _onUpdate(event) {
644
- if (this._metadata == null) {
645
- return;
646
- }
647
- const objectIds = getInlineChanges(event);
648
- if (objectIds.length === 0) {
649
- return;
650
- }
651
- const heads = getHeads(event.doc);
652
- const lastAvailableHash = heads.join("");
653
- if (!lastAvailableHash) {
654
- return;
655
- }
656
- const encodedIds = objectIds.map((objectId) => idCodec.encode({
657
- documentId: event.handle.documentId,
658
- objectId
659
- }));
660
- const idToLastHash = new Map(encodedIds.map((id) => [
661
- id,
662
- lastAvailableHash
663
- ]));
664
- const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
665
- this._updatingMetadata.delete(event.handle.documentId);
666
- }).catch((err) => {
667
- this._ctx.disposed && log3.catch(err, void 0, {
668
- F: __dxlog_file4,
669
- L: 209,
670
- S: this,
671
- C: (f, a) => f(...a)
672
- });
673
- });
674
- this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
675
- }
676
634
  _automergeDocs() {
677
635
  return mapValues(this._repo.handles, (handle) => ({
678
636
  state: handle.state,
@@ -703,7 +661,19 @@ var AutomergeHost = class {
703
661
  //
704
662
  async flush({ documentIds }) {
705
663
  await Promise.all(documentIds?.map((id) => this._repo.find(id).whenReady()) ?? []);
706
- await this._repo.flush(documentIds);
664
+ try {
665
+ await asyncTimeout(this._repo.flush(documentIds), 500);
666
+ } catch (err) {
667
+ log3.warn("flush error", {
668
+ documentIds,
669
+ err
670
+ }, {
671
+ F: __dxlog_file4,
672
+ L: 196,
673
+ S: this,
674
+ C: (f, a) => f(...a)
675
+ });
676
+ }
707
677
  }
708
678
  syncRepo(request) {
709
679
  return this._clientNetwork.syncRepo(request);
@@ -726,7 +696,7 @@ var AutomergeHost = class {
726
696
  deviceKey
727
697
  }, {
728
698
  F: __dxlog_file4,
729
- L: 276,
699
+ L: 221,
730
700
  S: this,
731
701
  C: (f, a) => f(...a)
732
702
  });
@@ -749,24 +719,6 @@ _ts_decorate([
749
719
  AutomergeHost = _ts_decorate([
750
720
  trace.resource()
751
721
  ], AutomergeHost);
752
- var getInlineChanges = (event) => {
753
- const inlineChangedObjectIds = /* @__PURE__ */ new Set();
754
- for (const { path } of event.patches) {
755
- if (path.length < 2) {
756
- continue;
757
- }
758
- switch (path[0]) {
759
- case "objects":
760
- if (path.length >= 2) {
761
- inlineChangedObjectIds.add(path[1]);
762
- }
763
- break;
764
- }
765
- }
766
- return [
767
- ...inlineChangedObjectIds
768
- ];
769
- };
770
722
  var getSpaceKeyFromDoc = (doc) => {
771
723
  const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
772
724
  if (rawSpaceKey == null) {
@@ -1058,7 +1010,7 @@ var AutomergeDocumentLoaderImpl = class {
1058
1010
  };
1059
1011
 
1060
1012
  // packages/core/echo/echo-pipeline/src/automerge/reference.ts
1061
- import { Reference } from "@dxos/echo-db";
1013
+ import { Reference } from "@dxos/echo-schema";
1062
1014
  var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
1063
1015
  var encodeReference = (reference) => ({
1064
1016
  "@type": REFERENCE_TYPE_TAG,
@@ -1076,6 +1028,7 @@ export {
1076
1028
  AutomergeHost,
1077
1029
  AutomergeStorageAdapter,
1078
1030
  DataServiceImpl,
1031
+ LevelDBStorageAdapter,
1079
1032
  LocalHostNetworkAdapter,
1080
1033
  MOCK_AUTH_PROVIDER,
1081
1034
  MOCK_AUTH_VERIFIER,
@@ -1094,6 +1047,7 @@ export {
1094
1047
  createMappedFeedWriter,
1095
1048
  decodeReference,
1096
1049
  encodeReference,
1050
+ encodingOptions,
1097
1051
  getSpaceKeyFromDoc,
1098
1052
  hasInvitationExpired,
1099
1053
  isEncodedReferenceObject,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/automerge/automerge-host.ts", "../../../src/automerge/leveldb-storage-adapter.ts", "../../../src/automerge/local-host-network-adapter.ts", "../../../src/automerge/mesh-network-adapter.ts", "../../../src/automerge/migrations.ts", "../../../src/automerge/automerge-storage-adapter.ts", "../../../src/automerge/automerge-doc-loader.ts", "../../../src/automerge/reference.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { next as automerge, getHeads } from '@dxos/automerge/automerge';\nimport {\n Repo,\n type PeerId,\n type DocumentId,\n type StorageKey,\n type DocHandle,\n type DocHandleChangePayload,\n type StorageAdapterInterface,\n} from '@dxos/automerge/automerge-repo';\nimport { type Stream } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { idCodec } from '@dxos/protocols';\nimport {\n type FlushRequest,\n type HostInfo,\n type SyncRepoRequest,\n type SyncRepoResponse,\n} from '@dxos/protocols/proto/dxos/echo/service';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { type AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\nimport { trace } from '@dxos/tracing';\nimport { ComplexMap, ComplexSet, type MaybePromise, defaultMap, mapValues } from '@dxos/util';\n\nimport { LevelDBStorageAdapter } from './leveldb-storage-adapter';\nimport { LocalHostNetworkAdapter } from './local-host-network-adapter';\nimport { MeshNetworkAdapter } from './mesh-network-adapter';\nimport { levelMigration } from './migrations';\nimport { type MySublevel } from './types';\n\nexport type { DocumentId };\n\nexport interface MetadataMethods {\n markDirty(idToLastHash: Map<string, string>): Promise<void>;\n}\n\nexport type AutomergeHostParams = {\n db: MaybePromise<MySublevel>;\n /**\n * For migration purposes.\n */\n directory?: Directory;\n metadata?: MetadataMethods;\n};\n\n@trace.resource()\nexport class AutomergeHost {\n private readonly _ctx = new Context();\n private readonly _directory?: Directory;\n private readonly _db: MaybePromise<MySublevel>;\n private readonly _metadata?: MetadataMethods;\n\n private _repo!: Repo;\n private _meshNetwork!: MeshNetworkAdapter;\n private _clientNetwork!: LocalHostNetworkAdapter;\n private _storage!: StorageAdapterInterface & { close?: () => void };\n\n @trace.info()\n private _peerId!: string;\n\n /**\n * spaceKey -> deviceKey[]\n */\n private readonly _authorizedDevices = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n private readonly _updatingMetadata = new Map<string, Promise<void>>();\n\n public _requestedDocs = new Set<string>();\n\n constructor({ directory, db, metadata }: AutomergeHostParams) {\n this._directory = directory;\n this._db = db;\n this._metadata = metadata;\n }\n\n async open() {\n this._directory && (await levelMigration({ db: await this._db, directory: this._directory }));\n this._storage = new LevelDBStorageAdapter({\n db: await this._db,\n callbacks: { beforeSave: (params) => this._beforeSave(params) },\n });\n this._peerId = `host-${PublicKey.random().toHex()}` as PeerId;\n\n this._meshNetwork = new MeshNetworkAdapter();\n this._clientNetwork = new LocalHostNetworkAdapter();\n this._repo = new Repo({\n peerId: this._peerId as PeerId,\n network: [this._clientNetwork, this._meshNetwork],\n storage: this._storage,\n\n // TODO(dmaretskyi): Share based on HALO permissions and space affinity.\n // Hosts, running in the worker, don't share documents unless requested by other peers.\n sharePolicy: async (peerId /* device key */, documentId /* space key */) => {\n if (peerId.startsWith('client-')) {\n return false; // Only send docs to clients if they are requested.\n }\n\n if (!documentId) {\n return false;\n }\n\n const doc = this._repo.handles[documentId]?.docSync();\n if (!doc) {\n const isRequested = this._requestedDocs.has(`automerge:${documentId}`);\n log('doc share policy check', { peerId, documentId, isRequested });\n return isRequested;\n }\n\n try {\n const spaceKey = getSpaceKeyFromDoc(doc);\n if (!spaceKey) {\n log('space key not found for share policy check', { peerId, documentId });\n return false;\n }\n\n const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));\n\n // TODO(mykola): Hack, stop abusing `peerMetadata` field.\n const deviceKeyHex = (this.repo.peerMetadataByPeerId[peerId] as any)?.dxos_deviceKey;\n if (!deviceKeyHex) {\n log('device key not found for share policy check', { peerId, documentId });\n return false;\n }\n const deviceKey = PublicKey.from(deviceKeyHex);\n\n const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;\n log('share policy check', {\n localPeer: this._peerId,\n remotePeer: peerId,\n documentId,\n deviceKey,\n spaceKey,\n isAuthorized,\n });\n return isAuthorized;\n } catch (err) {\n log.catch(err);\n return false;\n }\n },\n });\n this._clientNetwork.ready();\n this._meshNetwork.ready();\n\n {\n const listener = ({ handle }: { handle: DocHandle<any> }) => this._onDocument(handle);\n this._repo.on('document', listener);\n this._ctx.onDispose(() => {\n this._repo.off('document', listener);\n Object.values(this._repo.handles).forEach((handle) => handle.off('change'));\n });\n }\n\n await this._clientNetwork.whenConnected();\n }\n\n async close() {\n this._storage.close?.();\n await this._clientNetwork.close();\n await this._ctx.dispose();\n }\n\n get repo(): Repo {\n return this._repo;\n }\n\n private async _beforeSave(path: StorageKey) {\n const id = path[0];\n if (this._updatingMetadata.has(id)) {\n return this._updatingMetadata.get(id);\n }\n }\n\n private _onDocument(handle: DocHandle<any>) {\n const listener = (event: DocHandleChangePayload<any>) => this._onUpdate(event);\n handle.on('change', listener);\n }\n\n private _onUpdate(event: DocHandleChangePayload<any>) {\n if (this._metadata == null) {\n return;\n }\n\n const objectIds = getInlineChanges(event);\n if (objectIds.length === 0) {\n return;\n }\n\n const heads = getHeads(event.doc);\n const lastAvailableHash = heads.join('');\n if (!lastAvailableHash) {\n return;\n }\n\n const encodedIds = objectIds.map((objectId) => idCodec.encode({ documentId: event.handle.documentId, objectId }));\n const idToLastHash = new Map(encodedIds.map((id) => [id, lastAvailableHash]));\n const markingDirtyPromise = this._metadata\n .markDirty(idToLastHash)\n .then(() => {\n this._updatingMetadata.delete(event.handle.documentId);\n })\n .catch((err: Error) => {\n this._ctx.disposed && log.catch(err);\n });\n this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);\n }\n\n @trace.info({ depth: null })\n private _automergeDocs() {\n return mapValues(this._repo.handles, (handle) => ({\n state: handle.state,\n hasDoc: !!handle.docSync(),\n heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,\n data:\n handle.docSync() &&\n mapValues(handle.docSync(), (value, key) => {\n try {\n switch (key) {\n case 'access':\n case 'links':\n return value;\n case 'objects':\n return Object.keys(value as any);\n default:\n return `${value}`;\n }\n } catch (err) {\n return `${err}`;\n }\n }),\n }));\n }\n\n @trace.info({ depth: null })\n private _automergePeers() {\n return this._repo.peers;\n }\n\n //\n // Methods for client-services.\n //\n\n async flush({ documentIds }: FlushRequest): Promise<void> {\n // Note: Wait for all requested documents to be loaded/synced from thin-client.\n await Promise.all(documentIds?.map((id) => this._repo.find(id as DocumentId).whenReady()) ?? []);\n await this._repo.flush(documentIds as DocumentId[]);\n }\n\n syncRepo(request: SyncRepoRequest): Stream<SyncRepoResponse> {\n return this._clientNetwork.syncRepo(request);\n }\n\n sendSyncMessage(request: SyncRepoRequest): Promise<void> {\n return this._clientNetwork.sendSyncMessage(request);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n return this._clientNetwork.getHostInfo();\n }\n\n //\n // Mesh replication.\n //\n\n createExtension(): AutomergeReplicator {\n return this._meshNetwork.createExtension();\n }\n\n authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey) {\n log('authorizeDevice', { spaceKey, deviceKey });\n defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);\n }\n}\n\n// TODO(mykola): Reconcile with `getInlineAndLinkChanges` in AutomergeDB.\nconst getInlineChanges = (event: DocHandleChangePayload<any>) => {\n const inlineChangedObjectIds = new Set<string>();\n for (const { path } of event.patches) {\n if (path.length < 2) {\n continue;\n }\n switch (path[0]) {\n case 'objects':\n if (path.length >= 2) {\n inlineChangedObjectIds.add(path[1]);\n }\n break;\n }\n }\n return [...inlineChangedObjectIds];\n};\n\nexport const getSpaceKeyFromDoc = (doc: any): string | null => {\n // experimental_spaceKey is set on old documents, new ones are created with doc.access.spaceKey\n const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;\n if (rawSpaceKey == null) {\n return null;\n }\n\n return String(rawSpaceKey);\n};\n", "//\n// Copyright 2024 DXOS.org\n// s\n\nimport { type MixedEncoding } from 'level-transcoder';\n\nimport { type StorageAdapterInterface, type Chunk, type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { type MySublevel } from './types';\n\nexport type LevelDBStorageAdapterParams = {\n db: MySublevel;\n callbacks?: StorageCallbacks;\n};\n\nexport type StorageCallbacks = {\n beforeSave?: (path: StorageKey) => MaybePromise<void>;\n afterSave?: (path: StorageKey) => MaybePromise<void>;\n};\n\nexport class LevelDBStorageAdapter implements StorageAdapterInterface {\n private _state: 'opened' | 'closed' = 'opened';\n constructor(private readonly _params: LevelDBStorageAdapterParams) {}\n\n async load(keyArray: StorageKey): Promise<Uint8Array | undefined> {\n if (this._state !== 'opened') {\n return undefined;\n }\n return this._params.db\n .get<StorageKey, Uint8Array>(keyArray, { ...encodingOptions })\n .catch((err) => (err.code === 'LEVEL_NOT_FOUND' ? undefined : Promise.reject(err)));\n }\n\n async save(keyArray: StorageKey, binary: Uint8Array): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n await this._params.callbacks?.beforeSave?.(keyArray);\n await this._params.db.put<StorageKey, Uint8Array>(keyArray, Buffer.from(binary), {\n ...encodingOptions,\n });\n await this._params.callbacks?.afterSave?.(keyArray);\n }\n\n async remove(keyArray: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n await this._params.db.del<StorageKey>(keyArray, { ...encodingOptions });\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._state !== 'opened') {\n return [];\n }\n const result: Chunk[] = [];\n for await (const [key, value] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n result.push({\n key,\n data: value,\n });\n }\n return result;\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n for await (const [key] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n batch.del<StorageKey>(key, { ...encodingOptions });\n }\n await batch.write();\n }\n\n close() {\n this._state = 'closed';\n }\n}\n\nconst keyEncoder: MixedEncoding<StorageKey, Uint8Array, StorageKey> = {\n encode: (key: StorageKey): Uint8Array =>\n Buffer.from(key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-')),\n decode: (key: Uint8Array): StorageKey =>\n Buffer.from(key)\n .toString()\n .split('-')\n .map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%')),\n};\n\nexport const encodingOptions = {\n keyEncoding: keyEncoder,\n valueEncoding: 'buffer',\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { type HostInfo, type SyncRepoRequest, type SyncRepoResponse } from '@dxos/protocols/proto/dxos/echo/service';\n\ntype ClientSyncState = {\n connected: boolean;\n send: (message: Message) => void;\n disconnect: () => void;\n};\n\n/**\n * Used to replicate with apps running on the same device.\n */\nexport class LocalHostNetworkAdapter extends NetworkAdapter {\n private readonly _peers: Map<PeerId, ClientSyncState> = new Map();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n this.emit('ready', {\n network: this,\n });\n }\n\n private readonly _connected = new Trigger();\n private _isConnected: boolean = false;\n\n /**\n * Called by `Repo` to connect to the network.\n *\n * @param peerId Our peer Id.\n */\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._isConnected = true;\n this._connected.wake();\n // No-op. Client always connects first\n }\n\n override send(message: Message): void {\n const peer = this._peers.get(message.targetId);\n invariant(peer, 'Peer not found.');\n peer.send(message);\n }\n\n async close() {\n this._peers.forEach((peer) => peer.disconnect());\n this.emit('close');\n }\n\n override disconnect(): void {\n // TODO(mykola): `disconnect` is not used anywhere in `Repo` from `@automerge/automerge-repo`. Should we remove it?\n // No-op\n }\n\n async whenConnected(): Promise<void> {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n syncRepo({ id, syncMessage }: SyncRepoRequest): Stream<SyncRepoResponse> {\n const peerId = this._getPeerId(id);\n\n return new Stream(({ next, close }) => {\n invariant(!this._peers.has(peerId), 'Peer already connected.');\n this._peers.set(peerId, {\n connected: true,\n send: (message) => {\n next({\n syncMessage: cbor.encode(message),\n });\n },\n disconnect: () => {\n this._peers.delete(peerId);\n close();\n this.emit('peer-disconnected', {\n peerId,\n });\n },\n });\n\n invariant(this._isConnected);\n this.emit('peer-candidate', {\n peerMetadata: {},\n peerId,\n });\n });\n }\n\n async sendSyncMessage({ id, syncMessage }: SyncRepoRequest): Promise<void> {\n invariant(this._isConnected);\n const message = cbor.decode(syncMessage!) as Message;\n this.emit('message', message);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n invariant(this._isConnected);\n invariant(this.peerId, 'Peer id not set.');\n return {\n peerId: this.peerId,\n };\n }\n\n private _getPeerId(id: string): PeerId {\n return id as PeerId;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { type PeerInfo } from '@dxos/protocols/proto/dxos/mesh/teleport/automerge';\nimport { AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\n\n/**\n * Used to replicate with other peers over the network.\n */\nexport class MeshNetworkAdapter extends NetworkAdapter {\n private readonly _extensions: Map<string, AutomergeReplicator> = new Map();\n private _connected = new Trigger();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n this.emit('ready', {\n network: this,\n });\n }\n\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._connected.wake();\n }\n\n override send(message: Message): void {\n const receiverId = message.targetId;\n const extension = this._extensions.get(receiverId);\n invariant(extension, 'Extension not found.');\n extension.sendSyncMessage({ payload: cbor.encode(message) }).catch((err) => log.catch(err));\n }\n\n override disconnect(): void {\n // No-op\n }\n\n createExtension(): AutomergeReplicator {\n invariant(this.peerId, 'Peer id not set.');\n\n let peerInfo: PeerInfo;\n const extension = new AutomergeReplicator(\n {\n peerId: this.peerId,\n },\n {\n onStartReplication: async (info, remotePeerId /** Teleport ID */) => {\n await this._connected.wait();\n\n // Note: We store only one extension per peer.\n // There can be a case where two connected peers have more than one teleport connection between them\n // and each of them uses different teleport connections to send messages.\n // It works because we receive messages from all teleport connections and Automerge Repo dedup them.\n // TODO(mykola): Use only one teleport connection per peer.\n\n // TODO(dmaretskyi): Critical bug.\n // - two peers get connected via swarm 1\n // - they get connected via swarm 2\n // - swarm 1 gets disconnected\n // - automerge repo thinks that peer 2 got disconnected even though swarm 2 is still active\n\n log('onStartReplication', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n if (!this._extensions.has(info.id)) {\n peerInfo = info;\n // TODO(mykola): Fix race condition?\n this._extensions.set(info.id, extension);\n\n log('peer-candidate', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n this.emit('peer-candidate', {\n // TODO(mykola): Hack, stop abusing `peerMetadata` field.\n peerMetadata: {\n dxos_deviceKey: remotePeerId.toHex(),\n } as any,\n peerId: info.id as PeerId,\n });\n }\n },\n onSyncMessage: async ({ payload }) => {\n if (!peerInfo) {\n return;\n }\n const message = cbor.decode(payload) as Message;\n // Note: automerge Repo dedup messages.\n this.emit('message', message);\n },\n onClose: async () => {\n if (!peerInfo) {\n return;\n }\n this.emit('peer-disconnected', {\n peerId: peerInfo.id as PeerId,\n });\n this._extensions.delete(peerInfo.id);\n },\n },\n );\n return extension;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { IndexedDBStorageAdapter } from '@dxos/automerge/automerge-repo-storage-indexeddb';\nimport { log } from '@dxos/log';\nimport { StorageType, type Directory } from '@dxos/random-access-storage';\n\nimport { AutomergeStorageAdapter } from './automerge-storage-adapter';\nimport { encodingOptions } from './leveldb-storage-adapter';\nimport { type MySublevel } from './types';\n\nexport const levelMigration = async ({ db, directory }: { db: MySublevel; directory: Directory }) => {\n // Note: Make automigration from previous storage to leveldb here.\n const isNewLevel = !(await db\n .iterator<StorageKey, Uint8Array>({\n ...encodingOptions,\n })\n .next());\n\n if (!isNewLevel) {\n return;\n }\n\n const oldStorageAdapter =\n directory.type === StorageType.IDB\n ? new IndexedDBStorageAdapter(directory.path, 'data')\n : new AutomergeStorageAdapter(directory);\n\n const chunks = await oldStorageAdapter.loadRange([]);\n if (chunks.length === 0) {\n return;\n }\n const batch = db.batch();\n log.info('found chunks on old storage adapter', { chunks: chunks.length });\n for (const { key, data } of await oldStorageAdapter.loadRange([])) {\n data && batch.put<StorageKey, Uint8Array>(key, data, { ...encodingOptions });\n }\n await batch.write();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Chunk, type StorageKey, type StorageAdapterInterface } from '@dxos/automerge/automerge-repo';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { arrayToBuffer, bufferToArray } from '@dxos/util';\n\nexport class AutomergeStorageAdapter implements StorageAdapterInterface {\n // TODO(mykola): Hack for restricting automerge Repo to access storage if Host is `closed`.\n // Automerge Repo do not have any lifetime management.\n private _state: 'opened' | 'closed' = 'opened';\n\n constructor(private readonly _directory: Directory) {}\n\n async load(key: StorageKey): Promise<Uint8Array | undefined> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n const { size } = await file.stat();\n if (!size || size === 0) {\n return undefined;\n }\n const buffer = await file.read(0, size);\n return bufferToArray(buffer);\n }\n\n async save(key: StorageKey, data: Uint8Array): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n await file.write(0, arrayToBuffer(data));\n await file.truncate?.(data.length);\n\n await file.flush?.();\n }\n\n async remove(key: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n // TODO(dmaretskyi): Better deletion.\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n await file.destroy();\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._state !== 'opened') {\n return [];\n }\n const filename = this._getFilename(keyPrefix);\n const entries = await this._directory.list();\n return Promise.all(\n entries\n .filter((entry) => entry.startsWith(filename))\n .map(async (entry): Promise<Chunk> => {\n const file = this._directory.getOrCreateFile(entry);\n const { size } = await file.stat();\n const buffer = await file.read(0, size);\n return {\n key: this._getKeyFromFilename(entry),\n data: bufferToArray(buffer),\n };\n }),\n );\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(keyPrefix);\n const entries = await this._directory.list();\n await Promise.all(\n entries\n .filter((entry) => entry.startsWith(filename))\n .map(async (entry): Promise<void> => {\n const file = this._directory.getOrCreateFile(entry);\n await file.destroy();\n }),\n );\n }\n\n async close(): Promise<void> {\n this._state = 'closed';\n }\n\n private _getFilename(key: StorageKey): string {\n return key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-');\n }\n\n private _getKeyFromFilename(filename: string): StorageKey {\n return filename.split('-').map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%'));\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type DocHandle, type AutomergeUrl, type DocumentId, type Repo } from '@dxos/automerge/automerge-repo';\nimport { cancelWithContext, type Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SpaceState, type SpaceDoc } from './types';\n\ntype SpaceDocumentLinks = SpaceDoc['links'];\n\nexport interface AutomergeDocumentLoader {\n onObjectDocumentLoaded: Event<ObjectDocumentLoaded>;\n\n getAllHandles(): DocHandle<SpaceDoc>[];\n\n loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void>;\n loadObjectDocument(objectId: string): void;\n getSpaceRootDocHandle(): DocHandle<SpaceDoc>;\n createDocumentForObject(objectId: string): DocHandle<SpaceDoc>;\n onObjectLinksUpdated(links: SpaceDocumentLinks): void;\n onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string): void;\n\n /**\n * @returns objectIds for which we had document handles or were loading one.\n */\n clearHandleReferences(): string[];\n}\n\n/**\n * Manages object <-> docHandle binding and automerge document loading.\n */\nexport class AutomergeDocumentLoaderImpl implements AutomergeDocumentLoader {\n private _spaceRootDocHandle: DocHandle<SpaceDoc> | null = null;\n /**\n * An object id pointer to a handle of the document where the object is stored inline.\n */\n private readonly _objectDocumentHandles = new Map<string, DocHandle<SpaceDoc>>();\n /**\n * If object was requested via loadObjectDocument but root document links weren't updated yet\n * loading will be triggered in onObjectLinksUpdated callback.\n */\n private readonly _objectsPendingDocumentLoad = new Set<string>();\n\n public readonly onObjectDocumentLoaded = new Event<ObjectDocumentLoaded>();\n\n constructor(\n private readonly _spaceKey: PublicKey,\n private readonly _repo: Repo,\n ) {}\n\n getAllHandles(): DocHandle<SpaceDoc>[] {\n return [...new Set(this._objectDocumentHandles.values())];\n }\n\n public async loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void> {\n if (this._spaceRootDocHandle != null) {\n return;\n }\n if (!spaceState.rootUrl) {\n log.error('Database opened with no rootUrl', { spaceKey: this._spaceKey });\n this._createContextBoundSpaceRootDocument(ctx);\n } else {\n const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);\n const doc = existingDocHandle.docSync();\n invariant(doc);\n if (doc.access == null) {\n this._initDocAccess(existingDocHandle);\n }\n this._spaceRootDocHandle = existingDocHandle;\n }\n }\n\n public loadObjectDocument(objectId: string) {\n invariant(this._spaceRootDocHandle);\n if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {\n return;\n }\n const spaceRootDoc = this._spaceRootDocHandle.docSync();\n invariant(spaceRootDoc);\n const documentUrl = (spaceRootDoc.links ?? {})[objectId];\n if (documentUrl == null) {\n this._objectsPendingDocumentLoad.add(objectId);\n log.info('loading delayed until object links are initialized', { objectId });\n return;\n }\n this._loadLinkedObjects({ [objectId]: documentUrl });\n }\n\n public onObjectLinksUpdated(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n const linksAwaitingLoad = Object.entries(links).filter(([objectId]) =>\n this._objectsPendingDocumentLoad.has(objectId),\n );\n this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));\n linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));\n }\n\n public getSpaceRootDocHandle(): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n return this._spaceRootDocHandle;\n }\n\n public createDocumentForObject(objectId: string): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n const spaceDocHandle = this._repo.create<SpaceDoc>();\n this._initDocAccess(spaceDocHandle);\n this.onObjectBoundToDocument(spaceDocHandle, objectId);\n this._spaceRootDocHandle.change((newDoc: SpaceDoc) => {\n newDoc.links ??= {};\n newDoc.links[objectId] = spaceDocHandle.url;\n });\n return spaceDocHandle;\n }\n\n public onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string) {\n this._objectDocumentHandles.set(objectId, handle);\n }\n\n public clearHandleReferences(): string[] {\n const objectsWithHandles = [...this._objectDocumentHandles.keys()];\n this._objectDocumentHandles.clear();\n this._spaceRootDocHandle = null;\n return objectsWithHandles;\n }\n\n private _loadLinkedObjects(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n for (const [objectId, automergeUrl] of Object.entries(links)) {\n const logMeta = { objectId, automergeUrl };\n const objectDocumentHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {\n log.warn('object already inlined in a different document, ignoring the link', {\n ...logMeta,\n actualDocumentUrl: objectDocumentHandle.url,\n });\n continue;\n }\n if (objectDocumentHandle?.url === automergeUrl) {\n log.warn('object document was already loaded', logMeta);\n continue;\n }\n const handle = this._repo.find<SpaceDoc>(automergeUrl as DocumentId);\n log.debug('document loading triggered', logMeta);\n this._objectDocumentHandles.set(objectId, handle);\n void this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n\n private async _initDocHandle(ctx: Context, url: string) {\n const docHandle = this._repo.find<SpaceDoc>(url as DocumentId);\n while (true) {\n try {\n await warnAfterTimeout(5_000, 'Automerge root doc load timeout (AutomergeDb)', async () => {\n await cancelWithContext(ctx, docHandle.whenReady()); // TODO(dmaretskyi): Temporary 5s timeout for debugging.\n });\n break;\n } catch (err) {\n if (`${err}`.includes('Timeout')) {\n log.info('wraparound', { id: docHandle.documentId, state: docHandle.state });\n continue;\n }\n\n throw err;\n }\n }\n\n if (docHandle.state === 'unavailable') {\n throw new Error('Automerge document is unavailable');\n }\n\n return docHandle;\n }\n\n private _createContextBoundSpaceRootDocument(ctx: Context) {\n const docHandle = this._repo.create<SpaceDoc>();\n this._spaceRootDocHandle = docHandle;\n ctx.onDispose(() => {\n docHandle.delete();\n this._spaceRootDocHandle = null;\n });\n }\n\n private _initDocAccess(handle: DocHandle<SpaceDoc>) {\n handle.change((newDoc: SpaceDoc) => {\n newDoc.access ??= { spaceKey: this._spaceKey.toHex() };\n newDoc.access.spaceKey = this._spaceKey.toHex();\n });\n }\n\n private async _createObjectOnDocumentLoad(handle: DocHandle<SpaceDoc>, objectId: string) {\n try {\n await handle.doc(['ready']);\n const logMeta = { objectId, docUrl: handle.url };\n if (this.onObjectDocumentLoaded.listenerCount() === 0) {\n log.info('document loaded after all listeners were removed', logMeta);\n return;\n }\n const objectDocHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocHandle?.url !== handle.url) {\n log.warn('object was rebound while a document was loading, discarding handle', logMeta);\n return;\n }\n this.onObjectDocumentLoaded.emit({ handle, objectId });\n } catch (err) {\n const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;\n log.warn('failed to load a document', {\n objectId,\n automergeUrl: handle.url,\n retryLoading: shouldRetryLoading,\n err,\n });\n if (shouldRetryLoading) {\n await this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n }\n}\n\nexport interface ObjectDocumentLoaded {\n handle: DocHandle<SpaceDoc>;\n objectId: string;\n}\n\nexport interface DocumentChanges {\n createdObjectIds: string[];\n updatedObjectIds: string[];\n objectsToRebind: string[];\n linkedDocuments: {\n [echoId: string]: AutomergeUrl;\n };\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Reference } from '@dxos/echo-db';\n\nexport const REFERENCE_TYPE_TAG = 'dxos.echo.model.document.Reference';\n\n/**\n * Reference as it is stored in Automerge document.\n */\nexport type EncodedReferenceObject = {\n '@type': typeof REFERENCE_TYPE_TAG;\n itemId: string | null;\n protocol: string | null;\n host: string | null;\n};\n\nexport const encodeReference = (reference: Reference): EncodedReferenceObject => ({\n '@type': REFERENCE_TYPE_TAG,\n // NOTE: Automerge do not support undefined values, so we need to use null instead.\n itemId: reference.itemId ?? null,\n protocol: reference.protocol ?? null,\n host: reference.host ?? null,\n});\n\nexport const decodeReference = (value: any) =>\n new Reference(value.itemId, value.protocol ?? undefined, value.host ?? undefined);\n\nexport const isEncodedReferenceObject = (value: any): value is EncodedReferenceObject =>\n typeof value === 'object' && value !== null && value['@type'] === REFERENCE_TYPE_TAG;\n"],
5
- "mappings": "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",
6
- "names": ["next", "automerge", "getHeads", "Repo", "Context", "PublicKey", "log", "idCodec", "trace", "ComplexMap", "ComplexSet", "defaultMap", "mapValues", "LevelDBStorageAdapter", "constructor", "_params", "_state", "load", "keyArray", "undefined", "db", "get", "encodingOptions", "catch", "err", "code", "Promise", "reject", "save", "binary", "callbacks", "beforeSave", "put", "Buffer", "from", "afterSave", "remove", "del", "loadRange", "keyPrefix", "result", "key", "value", "iterator", "gte", "lte", "push", "data", "removeRange", "batch", "write", "close", "keyEncoder", "encode", "map", "k", "replaceAll", "join", "decode", "toString", "split", "keyEncoding", "valueEncoding", "Trigger", "NetworkAdapter", "cbor", "Stream", "invariant", "LocalHostNetworkAdapter", "_peers", "Map", "_connected", "_isConnected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "peer", "get", "targetId", "close", "forEach", "disconnect", "whenConnected", "wait", "timeout", "syncRepo", "id", "syncMessage", "_getPeerId", "next", "has", "set", "connected", "encode", "delete", "peerMetadata", "sendSyncMessage", "decode", "getHostInfo", "Trigger", "NetworkAdapter", "cbor", "invariant", "log", "AutomergeReplicator", "MeshNetworkAdapter", "_extensions", "Map", "_connected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "receiverId", "targetId", "extension", "get", "sendSyncMessage", "payload", "encode", "catch", "err", "disconnect", "createExtension", "peerInfo", "onStartReplication", "info", "remotePeerId", "wait", "id", "thisPeerId", "toHex", "has", "set", "peerMetadata", "dxos_deviceKey", "onSyncMessage", "decode", "onClose", "delete", "IndexedDBStorageAdapter", "log", "StorageType", "arrayToBuffer", "bufferToArray", "AutomergeStorageAdapter", "constructor", "_directory", "_state", "load", "key", "undefined", "filename", "_getFilename", "file", "getOrCreateFile", "size", "stat", "buffer", "read", "bufferToArray", "save", "data", "write", "arrayToBuffer", "truncate", "length", "flush", "remove", "destroy", "loadRange", "keyPrefix", "entries", "list", "Promise", "all", "filter", "entry", "startsWith", "map", "_getKeyFromFilename", "removeRange", "close", "k", "replaceAll", "join", "split", "levelMigration", "db", "directory", "isNewLevel", "iterator", "encodingOptions", "next", "oldStorageAdapter", "type", "StorageType", "IDB", "IndexedDBStorageAdapter", "path", "AutomergeStorageAdapter", "chunks", "loadRange", "length", "batch", "log", "info", "key", "data", "put", "write", "AutomergeHost", "constructor", "directory", "db", "metadata", "_ctx", "Context", "_authorizedDevices", "ComplexMap", "PublicKey", "hash", "_updatingMetadata", "Map", "_requestedDocs", "Set", "_directory", "_db", "_metadata", "open", "levelMigration", "_storage", "LevelDBStorageAdapter", "callbacks", "beforeSave", "params", "_beforeSave", "_peerId", "random", "toHex", "_meshNetwork", "MeshNetworkAdapter", "_clientNetwork", "LocalHostNetworkAdapter", "_repo", "Repo", "peerId", "network", "storage", "sharePolicy", "documentId", "startsWith", "doc", "handles", "docSync", "isRequested", "has", "log", "spaceKey", "getSpaceKeyFromDoc", "authorizedDevices", "get", "from", "deviceKeyHex", "repo", "peerMetadataByPeerId", "dxos_deviceKey", "deviceKey", "isAuthorized", "localPeer", "remotePeer", "err", "catch", "ready", "listener", "handle", "_onDocument", "on", "onDispose", "off", "Object", "values", "forEach", "whenConnected", "close", "dispose", "path", "id", "event", "_onUpdate", "objectIds", "getInlineChanges", "length", "heads", "getHeads", "lastAvailableHash", "join", "encodedIds", "map", "objectId", "idCodec", "encode", "idToLastHash", "markingDirtyPromise", "markDirty", "then", "delete", "disposed", "set", "_automergeDocs", "mapValues", "state", "hasDoc", "automerge", "data", "value", "key", "keys", "_automergePeers", "peers", "flush", "documentIds", "Promise", "all", "find", "whenReady", "syncRepo", "request", "sendSyncMessage", "getHostInfo", "createExtension", "authorizeDevice", "defaultMap", "ComplexSet", "add", "trace", "info", "depth", "resource", "inlineChangedObjectIds", "patches", "rawSpaceKey", "access", "experimental_spaceKey", "String", "Event", "cancelWithContext", "warnAfterTimeout", "invariant", "log", "AutomergeDocumentLoaderImpl", "constructor", "_spaceKey", "_repo", "_spaceRootDocHandle", "_objectDocumentHandles", "Map", "_objectsPendingDocumentLoad", "Set", "onObjectDocumentLoaded", "getAllHandles", "values", "loadSpaceRootDocHandle", "ctx", "spaceState", "rootUrl", "error", "spaceKey", "_createContextBoundSpaceRootDocument", "existingDocHandle", "_initDocHandle", "doc", "docSync", "access", "_initDocAccess", "loadObjectDocument", "objectId", "has", "spaceRootDoc", "documentUrl", "links", "add", "info", "_loadLinkedObjects", "onObjectLinksUpdated", "linksAwaitingLoad", "Object", "entries", "filter", "fromEntries", "forEach", "delete", "getSpaceRootDocHandle", "createDocumentForObject", "spaceDocHandle", "create", "onObjectBoundToDocument", "change", "newDoc", "url", "handle", "set", "clearHandleReferences", "objectsWithHandles", "keys", "clear", "automergeUrl", "logMeta", "objectDocumentHandle", "get", "warn", "actualDocumentUrl", "find", "debug", "_createObjectOnDocumentLoad", "docHandle", "whenReady", "err", "includes", "id", "documentId", "state", "Error", "onDispose", "toHex", "docUrl", "listenerCount", "objectDocHandle", "emit", "shouldRetryLoading", "retryLoading", "Reference", "REFERENCE_TYPE_TAG", "encodeReference", "reference", "itemId", "protocol", "host", "decodeReference", "value", "Reference", "undefined", "isEncodedReferenceObject"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { asyncTimeout } from '@dxos/async';\nimport { next as automerge } from '@dxos/automerge/automerge';\nimport { Repo, type DocumentId, type PeerId, type StorageAdapterInterface } from '@dxos/automerge/automerge-repo';\nimport { type Stream } from '@dxos/codec-protobuf';\nimport { Context, type Lifecycle } from '@dxos/context';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type FlushRequest,\n type HostInfo,\n type SyncRepoRequest,\n type SyncRepoResponse,\n} from '@dxos/protocols/proto/dxos/echo/service';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { type AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\nimport { trace } from '@dxos/tracing';\nimport { ComplexMap, ComplexSet, defaultMap, mapValues } from '@dxos/util';\n\nimport { LevelDBStorageAdapter, type StorageCallbacks } from './leveldb-storage-adapter';\nimport { LocalHostNetworkAdapter } from './local-host-network-adapter';\nimport { MeshNetworkAdapter } from './mesh-network-adapter';\nimport { levelMigration } from './migrations';\nimport { type SubLevelDB } from './types';\n\n// TODO: Remove\nexport type { DocumentId };\n\nexport type AutomergeHostParams = {\n db: SubLevelDB;\n /**\n * For migration purposes.\n */\n directory?: Directory;\n storageCallbacks?: StorageCallbacks;\n};\n\n@trace.resource()\nexport class AutomergeHost {\n private readonly _ctx = new Context();\n private readonly _directory?: Directory;\n private readonly _db: SubLevelDB;\n private readonly _storageCallbacks?: StorageCallbacks;\n\n private _repo!: Repo;\n private _meshNetwork!: MeshNetworkAdapter;\n private _clientNetwork!: LocalHostNetworkAdapter;\n private _storage!: StorageAdapterInterface & Lifecycle;\n\n @trace.info()\n private _peerId!: string;\n\n /**\n * spaceKey -> deviceKey[]\n */\n private readonly _authorizedDevices = new ComplexMap<PublicKey, ComplexSet<PublicKey>>(PublicKey.hash);\n\n public _requestedDocs = new Set<string>();\n\n constructor({ directory, db, storageCallbacks }: AutomergeHostParams) {\n this._directory = directory;\n this._db = db;\n this._storageCallbacks = storageCallbacks;\n }\n\n async open() {\n // TODO(mykola): remove this before 0.6 release.\n this._directory && (await levelMigration({ db: this._db, directory: this._directory }));\n this._storage = new LevelDBStorageAdapter({\n db: this._db,\n callbacks: this._storageCallbacks,\n });\n await this._storage.open?.();\n this._peerId = `host-${PublicKey.random().toHex()}` as PeerId;\n\n this._meshNetwork = new MeshNetworkAdapter();\n this._clientNetwork = new LocalHostNetworkAdapter();\n this._repo = new Repo({\n peerId: this._peerId as PeerId,\n network: [this._clientNetwork, this._meshNetwork],\n storage: this._storage,\n\n // TODO(dmaretskyi): Share based on HALO permissions and space affinity.\n // Hosts, running in the worker, don't share documents unless requested by other peers.\n sharePolicy: async (peerId /* device key */, documentId /* space key */) => {\n if (peerId.startsWith('client-')) {\n return false; // Only send docs to clients if they are requested.\n }\n\n if (!documentId) {\n return false;\n }\n\n const doc = this._repo.handles[documentId]?.docSync();\n if (!doc) {\n const isRequested = this._requestedDocs.has(`automerge:${documentId}`);\n log('doc share policy check', { peerId, documentId, isRequested });\n return isRequested;\n }\n\n try {\n const spaceKey = getSpaceKeyFromDoc(doc);\n if (!spaceKey) {\n log('space key not found for share policy check', { peerId, documentId });\n return false;\n }\n\n const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));\n\n // TODO(mykola): Hack, stop abusing `peerMetadata` field.\n const deviceKeyHex = (this.repo.peerMetadataByPeerId[peerId] as any)?.dxos_deviceKey;\n if (!deviceKeyHex) {\n log('device key not found for share policy check', { peerId, documentId });\n return false;\n }\n const deviceKey = PublicKey.from(deviceKeyHex);\n\n const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;\n log('share policy check', {\n localPeer: this._peerId,\n remotePeer: peerId,\n documentId,\n deviceKey,\n spaceKey,\n isAuthorized,\n });\n return isAuthorized;\n } catch (err) {\n log.catch(err);\n return false;\n }\n },\n });\n this._clientNetwork.ready();\n this._meshNetwork.ready();\n\n await this._clientNetwork.whenConnected();\n }\n\n async close() {\n await this._storage.close?.();\n await this._clientNetwork.close();\n await this._ctx.dispose();\n }\n\n get repo(): Repo {\n return this._repo;\n }\n\n @trace.info({ depth: null })\n private _automergeDocs() {\n return mapValues(this._repo.handles, (handle) => ({\n state: handle.state,\n hasDoc: !!handle.docSync(),\n heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,\n data:\n handle.docSync() &&\n mapValues(handle.docSync(), (value, key) => {\n try {\n switch (key) {\n case 'access':\n case 'links':\n return value;\n case 'objects':\n return Object.keys(value as any);\n default:\n return `${value}`;\n }\n } catch (err) {\n return `${err}`;\n }\n }),\n }));\n }\n\n @trace.info({ depth: null })\n private _automergePeers() {\n return this._repo.peers;\n }\n\n //\n // Methods for client-services.\n //\n\n async flush({ documentIds }: FlushRequest): Promise<void> {\n // Note: Wait for all requested documents to be loaded/synced from thin-client.\n await Promise.all(documentIds?.map((id) => this._repo.find(id as DocumentId).whenReady()) ?? []);\n\n // TODO(dmaretskyi): Workaround until the flush issue gets resolved.\n try {\n await asyncTimeout(this._repo.flush(documentIds as DocumentId[]), 500);\n } catch (err) {\n log.warn('flush error', { documentIds, err });\n }\n }\n\n syncRepo(request: SyncRepoRequest): Stream<SyncRepoResponse> {\n return this._clientNetwork.syncRepo(request);\n }\n\n sendSyncMessage(request: SyncRepoRequest): Promise<void> {\n return this._clientNetwork.sendSyncMessage(request);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n return this._clientNetwork.getHostInfo();\n }\n\n //\n // Mesh replication.\n //\n\n createExtension(): AutomergeReplicator {\n return this._meshNetwork.createExtension();\n }\n\n authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey) {\n log('authorizeDevice', { spaceKey, deviceKey });\n defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);\n }\n}\n\nexport const getSpaceKeyFromDoc = (doc: any): string | null => {\n // experimental_spaceKey is set on old documents, new ones are created with doc.access.spaceKey\n const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;\n if (rawSpaceKey == null) {\n return null;\n }\n\n return String(rawSpaceKey);\n};\n", "//\n// Copyright 2024 DXOS.org\n// s\n\nimport { type MixedEncoding } from 'level-transcoder';\n\nimport { type StorageAdapterInterface, type Chunk, type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { LifecycleState, Resource } from '@dxos/context';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { type BatchLevel, type SubLevelDB } from './types';\n\nexport type LevelDBStorageAdapterParams = {\n db: SubLevelDB;\n callbacks?: StorageCallbacks;\n};\n\nexport type BeforeSaveParams = { path: StorageKey; batch: BatchLevel };\n\nexport interface StorageCallbacks {\n beforeSave(params: BeforeSaveParams): MaybePromise<void>;\n afterSave(path: StorageKey): MaybePromise<void>;\n}\n\nexport class LevelDBStorageAdapter extends Resource implements StorageAdapterInterface {\n constructor(private readonly _params: LevelDBStorageAdapterParams) {\n super();\n }\n\n async load(keyArray: StorageKey): Promise<Uint8Array | undefined> {\n try {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n // TODO(mykola): this should be an error.\n return undefined;\n }\n return await this._params.db.get<StorageKey, Uint8Array>(keyArray, { ...encodingOptions });\n } catch (err: any) {\n if (isLevelDbNotFoundError(err)) {\n return undefined;\n }\n throw err;\n }\n }\n\n async save(keyArray: StorageKey, binary: Uint8Array): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n await this._params.callbacks?.beforeSave?.({ path: keyArray, batch });\n batch.put<StorageKey, Uint8Array>(keyArray, Buffer.from(binary), {\n ...encodingOptions,\n });\n await batch.write();\n\n await this._params.callbacks?.afterSave?.(keyArray);\n }\n\n async remove(keyArray: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n await this._params.db.del<StorageKey>(keyArray, { ...encodingOptions });\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return [];\n }\n const result: Chunk[] = [];\n for await (const [key, value] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n result.push({\n key,\n data: value,\n });\n }\n return result;\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return undefined;\n }\n const batch = this._params.db.batch();\n\n for await (const [key] of this._params.db.iterator<StorageKey, Uint8Array>({\n gte: keyPrefix,\n lte: [...keyPrefix, '\\uffff'],\n ...encodingOptions,\n })) {\n batch.del<StorageKey>(key, { ...encodingOptions });\n }\n await batch.write();\n }\n}\n\nconst keyEncoder: MixedEncoding<StorageKey, Uint8Array, StorageKey> = {\n encode: (key: StorageKey): Uint8Array =>\n Buffer.from(key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-')),\n decode: (key: Uint8Array): StorageKey =>\n Buffer.from(key)\n .toString()\n .split('-')\n .map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%')),\n};\n\nexport const encodingOptions = {\n keyEncoding: keyEncoder,\n valueEncoding: 'buffer',\n};\n\nconst isLevelDbNotFoundError = (err: any): boolean => err.code === 'LEVEL_NOT_FOUND';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { Stream } from '@dxos/codec-protobuf';\nimport { invariant } from '@dxos/invariant';\nimport { type HostInfo, type SyncRepoRequest, type SyncRepoResponse } from '@dxos/protocols/proto/dxos/echo/service';\n\ntype ClientSyncState = {\n connected: boolean;\n send: (message: Message) => void;\n disconnect: () => void;\n};\n\n/**\n * Used to replicate with apps running on the same device.\n */\nexport class LocalHostNetworkAdapter extends NetworkAdapter {\n private readonly _peers: Map<PeerId, ClientSyncState> = new Map();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n this.emit('ready', {\n network: this,\n });\n }\n\n private readonly _connected = new Trigger();\n private _isConnected: boolean = false;\n\n /**\n * Called by `Repo` to connect to the network.\n *\n * @param peerId Our peer Id.\n */\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._isConnected = true;\n this._connected.wake();\n // No-op. Client always connects first\n }\n\n override send(message: Message): void {\n const peer = this._peers.get(message.targetId);\n invariant(peer, 'Peer not found.');\n peer.send(message);\n }\n\n async close() {\n this._peers.forEach((peer) => peer.disconnect());\n this.emit('close');\n }\n\n override disconnect(): void {\n // TODO(mykola): `disconnect` is not used anywhere in `Repo` from `@automerge/automerge-repo`. Should we remove it?\n // No-op\n }\n\n async whenConnected(): Promise<void> {\n await this._connected.wait({ timeout: 10_000 });\n }\n\n syncRepo({ id, syncMessage }: SyncRepoRequest): Stream<SyncRepoResponse> {\n const peerId = this._getPeerId(id);\n\n return new Stream(({ next, close }) => {\n invariant(!this._peers.has(peerId), 'Peer already connected.');\n this._peers.set(peerId, {\n connected: true,\n send: (message) => {\n next({\n syncMessage: cbor.encode(message),\n });\n },\n disconnect: () => {\n this._peers.delete(peerId);\n close();\n this.emit('peer-disconnected', {\n peerId,\n });\n },\n });\n\n invariant(this._isConnected);\n this.emit('peer-candidate', {\n peerMetadata: {},\n peerId,\n });\n });\n }\n\n async sendSyncMessage({ id, syncMessage }: SyncRepoRequest): Promise<void> {\n invariant(this._isConnected);\n const message = cbor.decode(syncMessage!) as Message;\n this.emit('message', message);\n }\n\n async getHostInfo(): Promise<HostInfo> {\n invariant(this._isConnected);\n invariant(this.peerId, 'Peer id not set.');\n return {\n peerId: this.peerId,\n };\n }\n\n private _getPeerId(id: string): PeerId {\n return id as PeerId;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\nimport { NetworkAdapter, type Message, type PeerId, cbor } from '@dxos/automerge/automerge-repo';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { type PeerInfo } from '@dxos/protocols/proto/dxos/mesh/teleport/automerge';\nimport { AutomergeReplicator } from '@dxos/teleport-extension-automerge-replicator';\n\n/**\n * Used to replicate with other peers over the network.\n */\nexport class MeshNetworkAdapter extends NetworkAdapter {\n private readonly _extensions: Map<string, AutomergeReplicator> = new Map();\n private _connected = new Trigger();\n\n /**\n * Emits `ready` event. That signals to `Repo` that it can start using the adapter.\n */\n ready() {\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n this.emit('ready', {\n network: this,\n });\n }\n\n override connect(peerId: PeerId): void {\n this.peerId = peerId;\n this._connected.wake();\n }\n\n override send(message: Message): void {\n const receiverId = message.targetId;\n const extension = this._extensions.get(receiverId);\n invariant(extension, 'Extension not found.');\n extension.sendSyncMessage({ payload: cbor.encode(message) }).catch((err) => log.catch(err));\n }\n\n override disconnect(): void {\n // No-op\n }\n\n createExtension(): AutomergeReplicator {\n invariant(this.peerId, 'Peer id not set.');\n\n let peerInfo: PeerInfo;\n const extension = new AutomergeReplicator(\n {\n peerId: this.peerId,\n },\n {\n onStartReplication: async (info, remotePeerId /** Teleport ID */) => {\n await this._connected.wait();\n\n // Note: We store only one extension per peer.\n // There can be a case where two connected peers have more than one teleport connection between them\n // and each of them uses different teleport connections to send messages.\n // It works because we receive messages from all teleport connections and Automerge Repo dedup them.\n // TODO(mykola): Use only one teleport connection per peer.\n\n // TODO(dmaretskyi): Critical bug.\n // - two peers get connected via swarm 1\n // - they get connected via swarm 2\n // - swarm 1 gets disconnected\n // - automerge repo thinks that peer 2 got disconnected even though swarm 2 is still active\n\n log('onStartReplication', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n if (!this._extensions.has(info.id)) {\n peerInfo = info;\n // TODO(mykola): Fix race condition?\n this._extensions.set(info.id, extension);\n\n log('peer-candidate', { id: info.id, thisPeerId: this.peerId, remotePeerId: remotePeerId.toHex() });\n this.emit('peer-candidate', {\n // TODO(mykola): Hack, stop abusing `peerMetadata` field.\n peerMetadata: {\n dxos_deviceKey: remotePeerId.toHex(),\n } as any,\n peerId: info.id as PeerId,\n });\n }\n },\n onSyncMessage: async ({ payload }) => {\n if (!peerInfo) {\n return;\n }\n const message = cbor.decode(payload) as Message;\n // Note: automerge Repo dedup messages.\n this.emit('message', message);\n },\n onClose: async () => {\n if (!peerInfo) {\n return;\n }\n this.emit('peer-disconnected', {\n peerId: peerInfo.id as PeerId,\n });\n this._extensions.delete(peerInfo.id);\n },\n },\n );\n return extension;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type StorageKey } from '@dxos/automerge/automerge-repo';\nimport { IndexedDBStorageAdapter } from '@dxos/automerge/automerge-repo-storage-indexeddb';\nimport { log } from '@dxos/log';\nimport { StorageType, type Directory } from '@dxos/random-access-storage';\n\nimport { AutomergeStorageAdapter } from './automerge-storage-adapter';\nimport { encodingOptions } from './leveldb-storage-adapter';\nimport { type SubLevelDB } from './types';\n\nexport const levelMigration = async ({ db, directory }: { db: SubLevelDB; directory: Directory }) => {\n // Note: Make automigration from previous storage to leveldb here.\n const isNewLevel = !(await db\n .iterator<StorageKey, Uint8Array>({\n ...encodingOptions,\n })\n .next());\n\n if (!isNewLevel) {\n return;\n }\n\n const oldStorageAdapter =\n directory.type === StorageType.IDB\n ? new IndexedDBStorageAdapter(directory.path, 'data')\n : new AutomergeStorageAdapter(directory);\n\n const chunks = await oldStorageAdapter.loadRange([]);\n if (chunks.length === 0) {\n return;\n }\n const batch = db.batch();\n log.info('found chunks on old storage adapter', { chunks: chunks.length });\n for (const { key, data } of await oldStorageAdapter.loadRange([])) {\n data && batch.put<StorageKey, Uint8Array>(key, data, { ...encodingOptions });\n }\n await batch.write();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Chunk, type StorageKey, type StorageAdapterInterface } from '@dxos/automerge/automerge-repo';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { arrayToBuffer, bufferToArray } from '@dxos/util';\n\nexport class AutomergeStorageAdapter implements StorageAdapterInterface {\n // TODO(mykola): Hack for restricting automerge Repo to access storage if Host is `closed`.\n // Automerge Repo do not have any lifetime management.\n private _state: 'opened' | 'closed' = 'opened';\n\n constructor(private readonly _directory: Directory) {}\n\n async load(key: StorageKey): Promise<Uint8Array | undefined> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n const { size } = await file.stat();\n if (!size || size === 0) {\n return undefined;\n }\n const buffer = await file.read(0, size);\n return bufferToArray(buffer);\n }\n\n async save(key: StorageKey, data: Uint8Array): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n await file.write(0, arrayToBuffer(data));\n await file.truncate?.(data.length);\n\n await file.flush?.();\n }\n\n async remove(key: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n // TODO(dmaretskyi): Better deletion.\n const filename = this._getFilename(key);\n const file = this._directory.getOrCreateFile(filename);\n await file.destroy();\n }\n\n async loadRange(keyPrefix: StorageKey): Promise<Chunk[]> {\n if (this._state !== 'opened') {\n return [];\n }\n const filename = this._getFilename(keyPrefix);\n const entries = await this._directory.list();\n return Promise.all(\n entries\n .filter((entry) => entry.startsWith(filename))\n .map(async (entry): Promise<Chunk> => {\n const file = this._directory.getOrCreateFile(entry);\n const { size } = await file.stat();\n const buffer = await file.read(0, size);\n return {\n key: this._getKeyFromFilename(entry),\n data: bufferToArray(buffer),\n };\n }),\n );\n }\n\n async removeRange(keyPrefix: StorageKey): Promise<void> {\n if (this._state !== 'opened') {\n return undefined;\n }\n const filename = this._getFilename(keyPrefix);\n const entries = await this._directory.list();\n await Promise.all(\n entries\n .filter((entry) => entry.startsWith(filename))\n .map(async (entry): Promise<void> => {\n const file = this._directory.getOrCreateFile(entry);\n await file.destroy();\n }),\n );\n }\n\n async close(): Promise<void> {\n this._state = 'closed';\n }\n\n private _getFilename(key: StorageKey): string {\n return key.map((k) => k.replaceAll('%', '%25').replaceAll('-', '%2D')).join('-');\n }\n\n private _getKeyFromFilename(filename: string): StorageKey {\n return filename.split('-').map((k) => k.replaceAll('%2D', '-').replaceAll('%25', '%'));\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { type DocHandle, type AutomergeUrl, type DocumentId, type Repo } from '@dxos/automerge/automerge-repo';\nimport { cancelWithContext, type Context } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SpaceState, type SpaceDoc } from './types';\n\ntype SpaceDocumentLinks = SpaceDoc['links'];\n\nexport interface AutomergeDocumentLoader {\n onObjectDocumentLoaded: Event<ObjectDocumentLoaded>;\n\n getAllHandles(): DocHandle<SpaceDoc>[];\n\n loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void>;\n loadObjectDocument(objectId: string): void;\n getSpaceRootDocHandle(): DocHandle<SpaceDoc>;\n createDocumentForObject(objectId: string): DocHandle<SpaceDoc>;\n onObjectLinksUpdated(links: SpaceDocumentLinks): void;\n onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string): void;\n\n /**\n * @returns objectIds for which we had document handles or were loading one.\n */\n clearHandleReferences(): string[];\n}\n\n/**\n * Manages object <-> docHandle binding and automerge document loading.\n */\nexport class AutomergeDocumentLoaderImpl implements AutomergeDocumentLoader {\n private _spaceRootDocHandle: DocHandle<SpaceDoc> | null = null;\n /**\n * An object id pointer to a handle of the document where the object is stored inline.\n */\n private readonly _objectDocumentHandles = new Map<string, DocHandle<SpaceDoc>>();\n /**\n * If object was requested via loadObjectDocument but root document links weren't updated yet\n * loading will be triggered in onObjectLinksUpdated callback.\n */\n private readonly _objectsPendingDocumentLoad = new Set<string>();\n\n public readonly onObjectDocumentLoaded = new Event<ObjectDocumentLoaded>();\n\n constructor(\n private readonly _spaceKey: PublicKey,\n private readonly _repo: Repo,\n ) {}\n\n getAllHandles(): DocHandle<SpaceDoc>[] {\n return [...new Set(this._objectDocumentHandles.values())];\n }\n\n public async loadSpaceRootDocHandle(ctx: Context, spaceState: SpaceState): Promise<void> {\n if (this._spaceRootDocHandle != null) {\n return;\n }\n if (!spaceState.rootUrl) {\n log.error('Database opened with no rootUrl', { spaceKey: this._spaceKey });\n this._createContextBoundSpaceRootDocument(ctx);\n } else {\n const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);\n const doc = existingDocHandle.docSync();\n invariant(doc);\n if (doc.access == null) {\n this._initDocAccess(existingDocHandle);\n }\n this._spaceRootDocHandle = existingDocHandle;\n }\n }\n\n public loadObjectDocument(objectId: string) {\n invariant(this._spaceRootDocHandle);\n if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {\n return;\n }\n const spaceRootDoc = this._spaceRootDocHandle.docSync();\n invariant(spaceRootDoc);\n const documentUrl = (spaceRootDoc.links ?? {})[objectId];\n if (documentUrl == null) {\n this._objectsPendingDocumentLoad.add(objectId);\n log.info('loading delayed until object links are initialized', { objectId });\n return;\n }\n this._loadLinkedObjects({ [objectId]: documentUrl });\n }\n\n public onObjectLinksUpdated(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n const linksAwaitingLoad = Object.entries(links).filter(([objectId]) =>\n this._objectsPendingDocumentLoad.has(objectId),\n );\n this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));\n linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));\n }\n\n public getSpaceRootDocHandle(): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n return this._spaceRootDocHandle;\n }\n\n public createDocumentForObject(objectId: string): DocHandle<SpaceDoc> {\n invariant(this._spaceRootDocHandle);\n const spaceDocHandle = this._repo.create<SpaceDoc>();\n this._initDocAccess(spaceDocHandle);\n this.onObjectBoundToDocument(spaceDocHandle, objectId);\n this._spaceRootDocHandle.change((newDoc: SpaceDoc) => {\n newDoc.links ??= {};\n newDoc.links[objectId] = spaceDocHandle.url;\n });\n return spaceDocHandle;\n }\n\n public onObjectBoundToDocument(handle: DocHandle<SpaceDoc>, objectId: string) {\n this._objectDocumentHandles.set(objectId, handle);\n }\n\n public clearHandleReferences(): string[] {\n const objectsWithHandles = [...this._objectDocumentHandles.keys()];\n this._objectDocumentHandles.clear();\n this._spaceRootDocHandle = null;\n return objectsWithHandles;\n }\n\n private _loadLinkedObjects(links: SpaceDocumentLinks) {\n if (!links) {\n return;\n }\n for (const [objectId, automergeUrl] of Object.entries(links)) {\n const logMeta = { objectId, automergeUrl };\n const objectDocumentHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {\n log.warn('object already inlined in a different document, ignoring the link', {\n ...logMeta,\n actualDocumentUrl: objectDocumentHandle.url,\n });\n continue;\n }\n if (objectDocumentHandle?.url === automergeUrl) {\n log.warn('object document was already loaded', logMeta);\n continue;\n }\n const handle = this._repo.find<SpaceDoc>(automergeUrl as DocumentId);\n log.debug('document loading triggered', logMeta);\n this._objectDocumentHandles.set(objectId, handle);\n void this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n\n private async _initDocHandle(ctx: Context, url: string) {\n const docHandle = this._repo.find<SpaceDoc>(url as DocumentId);\n while (true) {\n try {\n await warnAfterTimeout(5_000, 'Automerge root doc load timeout (AutomergeDb)', async () => {\n await cancelWithContext(ctx, docHandle.whenReady()); // TODO(dmaretskyi): Temporary 5s timeout for debugging.\n });\n break;\n } catch (err) {\n if (`${err}`.includes('Timeout')) {\n log.info('wraparound', { id: docHandle.documentId, state: docHandle.state });\n continue;\n }\n\n throw err;\n }\n }\n\n if (docHandle.state === 'unavailable') {\n throw new Error('Automerge document is unavailable');\n }\n\n return docHandle;\n }\n\n private _createContextBoundSpaceRootDocument(ctx: Context) {\n const docHandle = this._repo.create<SpaceDoc>();\n this._spaceRootDocHandle = docHandle;\n ctx.onDispose(() => {\n docHandle.delete();\n this._spaceRootDocHandle = null;\n });\n }\n\n private _initDocAccess(handle: DocHandle<SpaceDoc>) {\n handle.change((newDoc: SpaceDoc) => {\n newDoc.access ??= { spaceKey: this._spaceKey.toHex() };\n newDoc.access.spaceKey = this._spaceKey.toHex();\n });\n }\n\n private async _createObjectOnDocumentLoad(handle: DocHandle<SpaceDoc>, objectId: string) {\n try {\n await handle.doc(['ready']);\n const logMeta = { objectId, docUrl: handle.url };\n if (this.onObjectDocumentLoaded.listenerCount() === 0) {\n log.info('document loaded after all listeners were removed', logMeta);\n return;\n }\n const objectDocHandle = this._objectDocumentHandles.get(objectId);\n if (objectDocHandle?.url !== handle.url) {\n log.warn('object was rebound while a document was loading, discarding handle', logMeta);\n return;\n }\n this.onObjectDocumentLoaded.emit({ handle, objectId });\n } catch (err) {\n const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;\n log.warn('failed to load a document', {\n objectId,\n automergeUrl: handle.url,\n retryLoading: shouldRetryLoading,\n err,\n });\n if (shouldRetryLoading) {\n await this._createObjectOnDocumentLoad(handle, objectId);\n }\n }\n }\n}\n\nexport interface ObjectDocumentLoaded {\n handle: DocHandle<SpaceDoc>;\n objectId: string;\n}\n\nexport interface DocumentChanges {\n createdObjectIds: string[];\n updatedObjectIds: string[];\n objectsToRebind: string[];\n linkedDocuments: {\n [echoId: string]: AutomergeUrl;\n };\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Reference } from '@dxos/echo-schema';\n\nexport const REFERENCE_TYPE_TAG = 'dxos.echo.model.document.Reference';\n\n/**\n * Reference as it is stored in Automerge document.\n */\nexport type EncodedReferenceObject = {\n '@type': typeof REFERENCE_TYPE_TAG;\n itemId: string | null;\n protocol: string | null;\n host: string | null;\n};\n\nexport const encodeReference = (reference: Reference): EncodedReferenceObject => ({\n '@type': REFERENCE_TYPE_TAG,\n // NOTE: Automerge do not support undefined values, so we need to use null instead.\n itemId: reference.itemId ?? null,\n protocol: reference.protocol ?? null,\n host: reference.host ?? null,\n});\n\nexport const decodeReference = (value: any) =>\n new Reference(value.itemId, value.protocol ?? undefined, value.host ?? undefined);\n\nexport const isEncodedReferenceObject = (value: any): value is EncodedReferenceObject =>\n typeof value === 'object' && value !== null && value['@type'] === REFERENCE_TYPE_TAG;\n"],
5
+ "mappings": "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",
6
+ "names": ["asyncTimeout", "next", "automerge", "Repo", "Context", "PublicKey", "log", "trace", "ComplexMap", "ComplexSet", "defaultMap", "mapValues", "LifecycleState", "Resource", "LevelDBStorageAdapter", "Resource", "constructor", "_params", "load", "keyArray", "_lifecycleState", "LifecycleState", "OPEN", "undefined", "db", "get", "encodingOptions", "err", "isLevelDbNotFoundError", "save", "binary", "batch", "callbacks", "beforeSave", "path", "put", "Buffer", "from", "write", "afterSave", "remove", "del", "loadRange", "keyPrefix", "result", "key", "value", "iterator", "gte", "lte", "push", "data", "removeRange", "keyEncoder", "encode", "map", "k", "replaceAll", "join", "decode", "toString", "split", "keyEncoding", "valueEncoding", "code", "Trigger", "NetworkAdapter", "cbor", "Stream", "invariant", "LocalHostNetworkAdapter", "_peers", "Map", "_connected", "_isConnected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "peer", "get", "targetId", "close", "forEach", "disconnect", "whenConnected", "wait", "timeout", "syncRepo", "id", "syncMessage", "_getPeerId", "next", "has", "set", "connected", "encode", "delete", "peerMetadata", "sendSyncMessage", "decode", "getHostInfo", "Trigger", "NetworkAdapter", "cbor", "invariant", "log", "AutomergeReplicator", "MeshNetworkAdapter", "_extensions", "Map", "_connected", "ready", "emit", "network", "connect", "peerId", "wake", "send", "message", "receiverId", "targetId", "extension", "get", "sendSyncMessage", "payload", "encode", "catch", "err", "disconnect", "createExtension", "peerInfo", "onStartReplication", "info", "remotePeerId", "wait", "id", "thisPeerId", "toHex", "has", "set", "peerMetadata", "dxos_deviceKey", "onSyncMessage", "decode", "onClose", "delete", "IndexedDBStorageAdapter", "log", "StorageType", "arrayToBuffer", "bufferToArray", "AutomergeStorageAdapter", "constructor", "_directory", "_state", "load", "key", "undefined", "filename", "_getFilename", "file", "getOrCreateFile", "size", "stat", "buffer", "read", "bufferToArray", "save", "data", "write", "arrayToBuffer", "truncate", "length", "flush", "remove", "destroy", "loadRange", "keyPrefix", "entries", "list", "Promise", "all", "filter", "entry", "startsWith", "map", "_getKeyFromFilename", "removeRange", "close", "k", "replaceAll", "join", "split", "levelMigration", "db", "directory", "isNewLevel", "iterator", "encodingOptions", "next", "oldStorageAdapter", "type", "StorageType", "IDB", "IndexedDBStorageAdapter", "path", "AutomergeStorageAdapter", "chunks", "loadRange", "length", "batch", "log", "info", "key", "data", "put", "write", "AutomergeHost", "constructor", "directory", "db", "storageCallbacks", "_ctx", "Context", "_authorizedDevices", "ComplexMap", "PublicKey", "hash", "_requestedDocs", "Set", "_directory", "_db", "_storageCallbacks", "open", "levelMigration", "_storage", "LevelDBStorageAdapter", "callbacks", "_peerId", "random", "toHex", "_meshNetwork", "MeshNetworkAdapter", "_clientNetwork", "LocalHostNetworkAdapter", "_repo", "Repo", "peerId", "network", "storage", "sharePolicy", "documentId", "startsWith", "doc", "handles", "docSync", "isRequested", "has", "log", "spaceKey", "getSpaceKeyFromDoc", "authorizedDevices", "get", "from", "deviceKeyHex", "repo", "peerMetadataByPeerId", "dxos_deviceKey", "deviceKey", "isAuthorized", "localPeer", "remotePeer", "err", "catch", "ready", "whenConnected", "close", "dispose", "_automergeDocs", "mapValues", "handle", "state", "hasDoc", "heads", "automerge", "getHeads", "data", "value", "key", "Object", "keys", "_automergePeers", "peers", "flush", "documentIds", "Promise", "all", "map", "id", "find", "whenReady", "asyncTimeout", "warn", "syncRepo", "request", "sendSyncMessage", "getHostInfo", "createExtension", "authorizeDevice", "defaultMap", "ComplexSet", "add", "trace", "info", "depth", "resource", "rawSpaceKey", "access", "experimental_spaceKey", "String", "Event", "cancelWithContext", "warnAfterTimeout", "invariant", "log", "AutomergeDocumentLoaderImpl", "constructor", "_spaceKey", "_repo", "_spaceRootDocHandle", "_objectDocumentHandles", "Map", "_objectsPendingDocumentLoad", "Set", "onObjectDocumentLoaded", "getAllHandles", "values", "loadSpaceRootDocHandle", "ctx", "spaceState", "rootUrl", "error", "spaceKey", "_createContextBoundSpaceRootDocument", "existingDocHandle", "_initDocHandle", "doc", "docSync", "access", "_initDocAccess", "loadObjectDocument", "objectId", "has", "spaceRootDoc", "documentUrl", "links", "add", "info", "_loadLinkedObjects", "onObjectLinksUpdated", "linksAwaitingLoad", "Object", "entries", "filter", "fromEntries", "forEach", "delete", "getSpaceRootDocHandle", "createDocumentForObject", "spaceDocHandle", "create", "onObjectBoundToDocument", "change", "newDoc", "url", "handle", "set", "clearHandleReferences", "objectsWithHandles", "keys", "clear", "automergeUrl", "logMeta", "objectDocumentHandle", "get", "warn", "actualDocumentUrl", "find", "debug", "_createObjectOnDocumentLoad", "docHandle", "whenReady", "err", "includes", "id", "documentId", "state", "Error", "onDispose", "toHex", "docUrl", "listenerCount", "objectDocHandle", "emit", "shouldRetryLoading", "retryLoading", "Reference", "REFERENCE_TYPE_TAG", "encodeReference", "reference", "itemId", "protocol", "host", "decodeReference", "value", "Reference", "undefined", "isEncodedReferenceObject"]
7
7
  }