@dxos/echo-pipeline 0.4.4-main.e05bf88 → 0.4.4-main.e80efb0

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 (28) hide show
  1. package/dist/lib/browser/{chunk-26G7ZQMP.mjs → chunk-WIB35LJH.mjs} +305 -254
  2. package/dist/lib/browser/{chunk-26G7ZQMP.mjs.map → chunk-WIB35LJH.mjs.map} +4 -4
  3. package/dist/lib/browser/index.mjs +5 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -1
  6. package/dist/lib/node/{chunk-V62AY27P.cjs → chunk-37RERU2L.cjs} +295 -248
  7. package/dist/lib/node/{chunk-V62AY27P.cjs.map → chunk-37RERU2L.cjs.map} +4 -4
  8. package/dist/lib/node/index.cjs +31 -27
  9. package/dist/lib/node/index.cjs.map +2 -2
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +16 -16
  12. package/dist/types/src/automerge/automerge-host.d.ts +5 -31
  13. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  14. package/dist/types/src/automerge/automerge-storage-adapter.d.ts +16 -0
  15. package/dist/types/src/automerge/automerge-storage-adapter.d.ts.map +1 -0
  16. package/dist/types/src/automerge/index.d.ts +4 -1
  17. package/dist/types/src/automerge/index.d.ts.map +1 -1
  18. package/dist/types/src/automerge/local-host-network-adapter.d.ts +23 -0
  19. package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -0
  20. package/dist/types/src/automerge/mesh-network-adapter.d.ts +18 -0
  21. package/dist/types/src/automerge/mesh-network-adapter.d.ts.map +1 -0
  22. package/package.json +34 -34
  23. package/src/automerge/automerge-host.test.ts +102 -2
  24. package/src/automerge/automerge-host.ts +27 -303
  25. package/src/automerge/automerge-storage-adapter.ts +105 -0
  26. package/src/automerge/index.ts +4 -1
  27. package/src/automerge/local-host-network-adapter.ts +109 -0
  28. package/src/automerge/mesh-network-adapter.ts +107 -0
@@ -2763,177 +2763,91 @@ SpaceManager = _ts_decorate8([
2763
2763
  trackLeaks4("open", "close")
2764
2764
  ], SpaceManager);
2765
2765
 
2766
- // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
2767
- import { Trigger as Trigger2 } from "@dxos/async";
2768
- import { next as automerge } from "@dxos/automerge/automerge";
2769
- import { Repo, NetworkAdapter, StorageAdapter, cbor } from "@dxos/automerge/automerge-repo";
2770
- import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
2771
- import { Stream as Stream2 } from "@dxos/codec-protobuf";
2772
- import { invariant as invariant10 } from "@dxos/invariant";
2773
- import { PublicKey as PublicKey8 } from "@dxos/keys";
2774
- import { log as log13 } from "@dxos/log";
2775
- import { StorageType } from "@dxos/random-access-storage";
2776
- import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
2777
- import { trace as trace6 } from "@dxos/tracing";
2778
- import { ComplexMap as ComplexMap7, ComplexSet, arrayToBuffer as arrayToBuffer2, bufferToArray, defaultMap, mapValues } from "@dxos/util";
2779
- function _ts_decorate9(decorators, target, key, desc) {
2780
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2781
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2782
- r = Reflect.decorate(decorators, target, key, desc);
2783
- else
2784
- for (var i = decorators.length - 1; i >= 0; i--)
2785
- if (d = decorators[i])
2786
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2787
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2788
- }
2789
- var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
2790
- var AutomergeHost = class {
2791
- constructor(storageDirectory) {
2792
- /**
2793
- * spaceKey -> deviceKey[]
2794
- */
2795
- this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
2796
- this._meshNetwork = new MeshNetworkAdapter();
2797
- this._clientNetwork = new LocalHostNetworkAdapter();
2798
- this._storage = storageDirectory.type === StorageType.IDB ? new IndexedDBStorageAdapter(storageDirectory.path, "data") : new AutomergeStorageAdapter(storageDirectory);
2799
- this._repo = new Repo({
2800
- peerId: `host-${PublicKey8.random().toHex()}`,
2801
- network: [
2802
- this._clientNetwork,
2803
- this._meshNetwork
2804
- ],
2805
- storage: this._storage,
2806
- // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
2807
- // Hosts, running in the worker, don't share documents unless requested by other peers.
2808
- sharePolicy: async (peerId, documentId) => {
2809
- if (peerId.startsWith("client-")) {
2810
- return true;
2811
- }
2812
- if (!documentId) {
2813
- return false;
2814
- }
2815
- const doc = this._repo.handles[documentId]?.docSync();
2816
- if (!doc) {
2817
- log13("doc not found for share policy check", {
2818
- peerId,
2819
- documentId
2820
- }, {
2821
- F: __dxlog_file14,
2822
- L: 68,
2823
- S: this,
2824
- C: (f, a) => f(...a)
2825
- });
2826
- return false;
2827
- }
2828
- try {
2829
- if (!doc.experimental_spaceKey) {
2830
- log13("space key not found for share policy check", {
2831
- peerId,
2832
- documentId
2833
- }, {
2834
- F: __dxlog_file14,
2835
- L: 74,
2836
- S: this,
2837
- C: (f, a) => f(...a)
2838
- });
2839
- return false;
2840
- }
2841
- const spaceKey = PublicKey8.from(doc.experimental_spaceKey);
2842
- const authorizedDevices = this._authorizedDevices.get(spaceKey);
2843
- const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
2844
- if (!deviceKeyHex) {
2845
- log13("device key not found for share policy check", {
2846
- peerId,
2847
- documentId
2848
- }, {
2849
- F: __dxlog_file14,
2850
- L: 84,
2851
- S: this,
2852
- C: (f, a) => f(...a)
2853
- });
2854
- return false;
2855
- }
2856
- const deviceKey = PublicKey8.from(deviceKeyHex);
2857
- const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
2858
- log13("share policy check", {
2859
- peerId,
2860
- documentId,
2861
- deviceKey,
2862
- spaceKey,
2863
- isAuthorized
2864
- }, {
2865
- F: __dxlog_file14,
2866
- L: 90,
2867
- S: this,
2868
- C: (f, a) => f(...a)
2869
- });
2870
- return isAuthorized;
2871
- } catch (err) {
2872
- log13.catch(err, void 0, {
2873
- F: __dxlog_file14,
2874
- L: 93,
2875
- S: this,
2876
- C: (f, a) => f(...a)
2877
- });
2878
- return false;
2879
- }
2880
- }
2881
- });
2882
- this._clientNetwork.ready();
2883
- this._meshNetwork.ready();
2884
- }
2885
- get repo() {
2886
- return this._repo;
2766
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
2767
+ import { StorageAdapter } from "@dxos/automerge/automerge-repo";
2768
+ import { arrayToBuffer as arrayToBuffer2, bufferToArray } from "@dxos/util";
2769
+ var AutomergeStorageAdapter = class extends StorageAdapter {
2770
+ constructor(_directory) {
2771
+ super();
2772
+ this._directory = _directory;
2773
+ this._state = "opened";
2887
2774
  }
2888
- _automergeDocs() {
2889
- return mapValues(this._repo.handles, (handle) => ({
2890
- state: handle.state,
2891
- hasDoc: !!handle.docSync(),
2892
- heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null
2893
- }));
2775
+ async load(key) {
2776
+ if (this._state !== "opened") {
2777
+ return void 0;
2778
+ }
2779
+ const filename = this._getFilename(key);
2780
+ const file = this._directory.getOrCreateFile(filename);
2781
+ const { size } = await file.stat();
2782
+ if (!size || size === 0) {
2783
+ return void 0;
2784
+ }
2785
+ const buffer = await file.read(0, size);
2786
+ return bufferToArray(buffer);
2894
2787
  }
2895
- _automergePeers() {
2896
- return this._repo.peers;
2788
+ async save(key, data) {
2789
+ if (this._state !== "opened") {
2790
+ return void 0;
2791
+ }
2792
+ const filename = this._getFilename(key);
2793
+ const file = this._directory.getOrCreateFile(filename);
2794
+ await file.write(0, arrayToBuffer2(data));
2795
+ await file.truncate?.(data.length);
2796
+ await file.flush?.();
2897
2797
  }
2898
- async close() {
2899
- this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
2900
- await this._clientNetwork.close();
2798
+ async remove(key) {
2799
+ if (this._state !== "opened") {
2800
+ return void 0;
2801
+ }
2802
+ const filename = this._getFilename(key);
2803
+ const file = this._directory.getOrCreateFile(filename);
2804
+ await file.destroy();
2901
2805
  }
2902
- //
2903
- // Methods for client-services.
2904
- //
2905
- syncRepo(request) {
2906
- return this._clientNetwork.syncRepo(request);
2806
+ async loadRange(keyPrefix) {
2807
+ if (this._state !== "opened") {
2808
+ return [];
2809
+ }
2810
+ const filename = this._getFilename(keyPrefix);
2811
+ const entries = await this._directory.list();
2812
+ return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
2813
+ const file = this._directory.getOrCreateFile(entry);
2814
+ const { size } = await file.stat();
2815
+ const buffer = await file.read(0, size);
2816
+ return {
2817
+ key: this._getKeyFromFilename(entry),
2818
+ data: bufferToArray(buffer)
2819
+ };
2820
+ }));
2907
2821
  }
2908
- sendSyncMessage(request) {
2909
- return this._clientNetwork.sendSyncMessage(request);
2822
+ async removeRange(keyPrefix) {
2823
+ if (this._state !== "opened") {
2824
+ return void 0;
2825
+ }
2826
+ const filename = this._getFilename(keyPrefix);
2827
+ const entries = await this._directory.list();
2828
+ await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
2829
+ const file = this._directory.getOrCreateFile(entry);
2830
+ await file.destroy();
2831
+ }));
2910
2832
  }
2911
- async getHostInfo() {
2912
- return this._clientNetwork.getHostInfo();
2833
+ async close() {
2834
+ this._state = "closed";
2913
2835
  }
2914
- //
2915
- // Mesh replication.
2916
- //
2917
- createExtension() {
2918
- return this._meshNetwork.createExtension();
2836
+ _getFilename(key) {
2837
+ return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
2919
2838
  }
2920
- authorizeDevice(spaceKey, deviceKey) {
2921
- defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
2839
+ _getKeyFromFilename(filename) {
2840
+ return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
2922
2841
  }
2923
2842
  };
2924
- _ts_decorate9([
2925
- trace6.info({
2926
- depth: null
2927
- })
2928
- ], AutomergeHost.prototype, "_automergeDocs", null);
2929
- _ts_decorate9([
2930
- trace6.info({
2931
- depth: null
2932
- })
2933
- ], AutomergeHost.prototype, "_automergePeers", null);
2934
- AutomergeHost = _ts_decorate9([
2935
- trace6.resource()
2936
- ], AutomergeHost);
2843
+
2844
+ // packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
2845
+ import { Trigger as Trigger2 } from "@dxos/async";
2846
+ import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
2847
+ import { Stream as Stream2 } from "@dxos/codec-protobuf";
2848
+ import { invariant as invariant10 } from "@dxos/invariant";
2849
+ import { log as log13 } from "@dxos/log";
2850
+ var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
2937
2851
  var LocalHostNetworkAdapter = class extends NetworkAdapter {
2938
2852
  constructor() {
2939
2853
  super(...arguments);
@@ -2956,7 +2870,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2956
2870
  const peer = this._peers.get(message.targetId);
2957
2871
  invariant10(peer, "Peer not found.", {
2958
2872
  F: __dxlog_file14,
2959
- L: 187,
2873
+ L: 45,
2960
2874
  S: this,
2961
2875
  A: [
2962
2876
  "peer",
@@ -2976,7 +2890,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2976
2890
  return new Stream2(({ next, close }) => {
2977
2891
  invariant10(!this._peers.has(peerId), "Peer already connected.", {
2978
2892
  F: __dxlog_file14,
2979
- L: 205,
2893
+ L: 63,
2980
2894
  S: this,
2981
2895
  A: [
2982
2896
  "!this._peers.has(peerId)",
@@ -3007,7 +2921,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
3007
2921
  });
3008
2922
  }).catch((err) => log13.catch(err, void 0, {
3009
2923
  F: __dxlog_file14,
3010
- L: 230,
2924
+ L: 88,
3011
2925
  S: this,
3012
2926
  C: (f, a) => f(...a)
3013
2927
  }));
@@ -3026,7 +2940,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
3026
2940
  });
3027
2941
  invariant10(this.peerId, "Peer id not set.", {
3028
2942
  F: __dxlog_file14,
3029
- L: 242,
2943
+ L: 100,
3030
2944
  S: this,
3031
2945
  A: [
3032
2946
  "this.peerId",
@@ -3041,11 +2955,19 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
3041
2955
  return id;
3042
2956
  }
3043
2957
  };
3044
- var MeshNetworkAdapter = class extends NetworkAdapter {
2958
+
2959
+ // packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
2960
+ import { Trigger as Trigger3 } from "@dxos/async";
2961
+ import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
2962
+ import { invariant as invariant11 } from "@dxos/invariant";
2963
+ import { log as log14 } from "@dxos/log";
2964
+ import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
2965
+ var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
2966
+ var MeshNetworkAdapter = class extends NetworkAdapter2 {
3045
2967
  constructor() {
3046
2968
  super(...arguments);
3047
2969
  this._extensions = /* @__PURE__ */ new Map();
3048
- this._connected = new Trigger2();
2970
+ this._connected = new Trigger3();
3049
2971
  }
3050
2972
  /**
3051
2973
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -3062,9 +2984,9 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
3062
2984
  send(message) {
3063
2985
  const receiverId = message.targetId;
3064
2986
  const extension = this._extensions.get(receiverId);
3065
- invariant10(extension, "Extension not found.", {
3066
- F: __dxlog_file14,
3067
- L: 279,
2987
+ invariant11(extension, "Extension not found.", {
2988
+ F: __dxlog_file15,
2989
+ L: 38,
3068
2990
  S: this,
3069
2991
  A: [
3070
2992
  "extension",
@@ -3072,10 +2994,10 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
3072
2994
  ]
3073
2995
  });
3074
2996
  extension.sendSyncMessage({
3075
- payload: cbor.encode(message)
3076
- }).catch((err) => log13.catch(err, void 0, {
3077
- F: __dxlog_file14,
3078
- L: 280,
2997
+ payload: cbor2.encode(message)
2998
+ }).catch((err) => log14.catch(err, void 0, {
2999
+ F: __dxlog_file15,
3000
+ L: 39,
3079
3001
  S: this,
3080
3002
  C: (f, a) => f(...a)
3081
3003
  }));
@@ -3083,9 +3005,9 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
3083
3005
  disconnect() {
3084
3006
  }
3085
3007
  createExtension() {
3086
- invariant10(this.peerId, "Peer id not set.", {
3087
- F: __dxlog_file14,
3088
- L: 288,
3008
+ invariant11(this.peerId, "Peer id not set.", {
3009
+ F: __dxlog_file15,
3010
+ L: 47,
3089
3011
  S: this,
3090
3012
  A: [
3091
3013
  "this.peerId",
@@ -3098,24 +3020,43 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
3098
3020
  }, {
3099
3021
  onStartReplication: async (info, remotePeerId) => {
3100
3022
  await this._connected.wait();
3023
+ log14("onStartReplication", {
3024
+ id: info.id,
3025
+ thisPeerId: this.peerId,
3026
+ remotePeerId: remotePeerId.toHex()
3027
+ }, {
3028
+ F: __dxlog_file15,
3029
+ L: 70,
3030
+ S: this,
3031
+ C: (f, a) => f(...a)
3032
+ });
3101
3033
  if (!this._extensions.has(info.id)) {
3102
3034
  peerInfo = info;
3103
3035
  this._extensions.set(info.id, extension);
3104
- } else {
3105
- this.emit("peer-disconnected", {
3036
+ log14("peer-candidate", {
3037
+ id: info.id,
3038
+ thisPeerId: this.peerId,
3039
+ remotePeerId: remotePeerId.toHex()
3040
+ }, {
3041
+ F: __dxlog_file15,
3042
+ L: 76,
3043
+ S: this,
3044
+ C: (f, a) => f(...a)
3045
+ });
3046
+ this.emit("peer-candidate", {
3047
+ // TODO(mykola): Hack, stop abusing `peerMetadata` field.
3048
+ peerMetadata: {
3049
+ dxos_deviceKey: remotePeerId.toHex()
3050
+ },
3106
3051
  peerId: info.id
3107
3052
  });
3108
3053
  }
3109
- this.emit("peer-candidate", {
3110
- // TODO(mykola): Hack, stop abusing `peerMetadata` field.
3111
- peerMetadata: {
3112
- dxos_deviceKey: remotePeerId.toHex()
3113
- },
3114
- peerId: info.id
3115
- });
3116
3054
  },
3117
3055
  onSyncMessage: async ({ payload }) => {
3118
- const message = cbor.decode(payload);
3056
+ if (!peerInfo) {
3057
+ return;
3058
+ }
3059
+ const message = cbor2.decode(payload);
3119
3060
  this.emit("message", message);
3120
3061
  },
3121
3062
  onClose: async () => {
@@ -3131,80 +3072,188 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
3131
3072
  return extension;
3132
3073
  }
3133
3074
  };
3134
- var AutomergeStorageAdapter = class extends StorageAdapter {
3135
- constructor(_directory) {
3136
- super();
3137
- this._directory = _directory;
3138
- this._state = "opened";
3139
- }
3140
- async load(key) {
3141
- if (this._state !== "opened") {
3142
- return void 0;
3143
- }
3144
- const filename = this._getFilename(key);
3145
- const file = this._directory.getOrCreateFile(filename);
3146
- const { size } = await file.stat();
3147
- if (!size || size === 0) {
3148
- return void 0;
3149
- }
3150
- const buffer = await file.read(0, size);
3151
- return bufferToArray(buffer);
3152
- }
3153
- async save(key, data) {
3154
- if (this._state !== "opened") {
3155
- return void 0;
3156
- }
3157
- const filename = this._getFilename(key);
3158
- const file = this._directory.getOrCreateFile(filename);
3159
- await file.write(0, arrayToBuffer2(data));
3160
- await file.truncate?.(data.length);
3161
- await file.flush?.();
3075
+
3076
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
3077
+ import { next as automerge } from "@dxos/automerge/automerge";
3078
+ import { Repo } from "@dxos/automerge/automerge-repo";
3079
+ import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
3080
+ import { PublicKey as PublicKey8 } from "@dxos/keys";
3081
+ import { log as log15 } from "@dxos/log";
3082
+ import { StorageType } from "@dxos/random-access-storage";
3083
+ import { trace as trace6 } from "@dxos/tracing";
3084
+ import { ComplexMap as ComplexMap7, ComplexSet, defaultMap, mapValues } from "@dxos/util";
3085
+ function _ts_decorate9(decorators, target, key, desc) {
3086
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3087
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3088
+ r = Reflect.decorate(decorators, target, key, desc);
3089
+ else
3090
+ for (var i = decorators.length - 1; i >= 0; i--)
3091
+ if (d = decorators[i])
3092
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3093
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3094
+ }
3095
+ var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
3096
+ var AutomergeHost = class {
3097
+ constructor(storageDirectory) {
3098
+ /**
3099
+ * spaceKey -> deviceKey[]
3100
+ */
3101
+ this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
3102
+ this._requestedDocs = /* @__PURE__ */ new Set();
3103
+ this._meshNetwork = new MeshNetworkAdapter();
3104
+ this._clientNetwork = new LocalHostNetworkAdapter();
3105
+ this._storage = storageDirectory.type === StorageType.IDB ? new IndexedDBStorageAdapter(storageDirectory.path, "data") : new AutomergeStorageAdapter(storageDirectory);
3106
+ const localPeerId = `host-${PublicKey8.random().toHex()}`;
3107
+ this._repo = new Repo({
3108
+ peerId: localPeerId,
3109
+ network: [
3110
+ this._clientNetwork,
3111
+ this._meshNetwork
3112
+ ],
3113
+ storage: this._storage,
3114
+ // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
3115
+ // Hosts, running in the worker, don't share documents unless requested by other peers.
3116
+ sharePolicy: async (peerId, documentId) => {
3117
+ if (peerId.startsWith("client-")) {
3118
+ return true;
3119
+ }
3120
+ if (!documentId) {
3121
+ return false;
3122
+ }
3123
+ const doc = this._repo.handles[documentId]?.docSync();
3124
+ if (!doc) {
3125
+ const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
3126
+ log15("doc share policy check", {
3127
+ peerId,
3128
+ documentId,
3129
+ isRequested
3130
+ }, {
3131
+ F: __dxlog_file16,
3132
+ L: 66,
3133
+ S: this,
3134
+ C: (f, a) => f(...a)
3135
+ });
3136
+ return isRequested;
3137
+ }
3138
+ try {
3139
+ if (!doc.experimental_spaceKey) {
3140
+ log15("space key not found for share policy check", {
3141
+ peerId,
3142
+ documentId
3143
+ }, {
3144
+ F: __dxlog_file16,
3145
+ L: 72,
3146
+ S: this,
3147
+ C: (f, a) => f(...a)
3148
+ });
3149
+ return false;
3150
+ }
3151
+ const spaceKey = PublicKey8.from(doc.experimental_spaceKey);
3152
+ const authorizedDevices = this._authorizedDevices.get(spaceKey);
3153
+ const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
3154
+ if (!deviceKeyHex) {
3155
+ log15("device key not found for share policy check", {
3156
+ peerId,
3157
+ documentId
3158
+ }, {
3159
+ F: __dxlog_file16,
3160
+ L: 82,
3161
+ S: this,
3162
+ C: (f, a) => f(...a)
3163
+ });
3164
+ return false;
3165
+ }
3166
+ const deviceKey = PublicKey8.from(deviceKeyHex);
3167
+ const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
3168
+ log15("share policy check", {
3169
+ localPeer: localPeerId,
3170
+ remotePeer: peerId,
3171
+ documentId,
3172
+ deviceKey,
3173
+ spaceKey,
3174
+ isAuthorized
3175
+ }, {
3176
+ F: __dxlog_file16,
3177
+ L: 88,
3178
+ S: this,
3179
+ C: (f, a) => f(...a)
3180
+ });
3181
+ return isAuthorized;
3182
+ } catch (err) {
3183
+ log15.catch(err, void 0, {
3184
+ F: __dxlog_file16,
3185
+ L: 98,
3186
+ S: this,
3187
+ C: (f, a) => f(...a)
3188
+ });
3189
+ return false;
3190
+ }
3191
+ }
3192
+ });
3193
+ this._clientNetwork.ready();
3194
+ this._meshNetwork.ready();
3162
3195
  }
3163
- async remove(key) {
3164
- if (this._state !== "opened") {
3165
- return void 0;
3166
- }
3167
- const filename = this._getFilename(key);
3168
- const file = this._directory.getOrCreateFile(filename);
3169
- await file.destroy();
3196
+ get repo() {
3197
+ return this._repo;
3170
3198
  }
3171
- async loadRange(keyPrefix) {
3172
- if (this._state !== "opened") {
3173
- return [];
3174
- }
3175
- const filename = this._getFilename(keyPrefix);
3176
- const entries = await this._directory.list();
3177
- return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
3178
- const file = this._directory.getOrCreateFile(entry);
3179
- const { size } = await file.stat();
3180
- const buffer = await file.read(0, size);
3181
- return {
3182
- key: this._getKeyFromFilename(entry),
3183
- data: bufferToArray(buffer)
3184
- };
3199
+ _automergeDocs() {
3200
+ return mapValues(this._repo.handles, (handle) => ({
3201
+ state: handle.state,
3202
+ hasDoc: !!handle.docSync(),
3203
+ heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null
3185
3204
  }));
3186
3205
  }
3187
- async removeRange(keyPrefix) {
3188
- if (this._state !== "opened") {
3189
- return void 0;
3190
- }
3191
- const filename = this._getFilename(keyPrefix);
3192
- const entries = await this._directory.list();
3193
- await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
3194
- const file = this._directory.getOrCreateFile(entry);
3195
- await file.destroy();
3196
- }));
3206
+ _automergePeers() {
3207
+ return this._repo.peers;
3197
3208
  }
3198
3209
  async close() {
3199
- this._state = "closed";
3210
+ this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
3211
+ await this._clientNetwork.close();
3200
3212
  }
3201
- _getFilename(key) {
3202
- return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
3213
+ //
3214
+ // Methods for client-services.
3215
+ //
3216
+ syncRepo(request) {
3217
+ return this._clientNetwork.syncRepo(request);
3203
3218
  }
3204
- _getKeyFromFilename(filename) {
3205
- return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
3219
+ sendSyncMessage(request) {
3220
+ return this._clientNetwork.sendSyncMessage(request);
3221
+ }
3222
+ async getHostInfo() {
3223
+ return this._clientNetwork.getHostInfo();
3224
+ }
3225
+ //
3226
+ // Mesh replication.
3227
+ //
3228
+ createExtension() {
3229
+ return this._meshNetwork.createExtension();
3230
+ }
3231
+ authorizeDevice(spaceKey, deviceKey) {
3232
+ log15("authorizeDevice", {
3233
+ spaceKey,
3234
+ deviceKey
3235
+ }, {
3236
+ F: __dxlog_file16,
3237
+ L: 155,
3238
+ S: this,
3239
+ C: (f, a) => f(...a)
3240
+ });
3241
+ defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
3206
3242
  }
3207
3243
  };
3244
+ _ts_decorate9([
3245
+ trace6.info({
3246
+ depth: null
3247
+ })
3248
+ ], AutomergeHost.prototype, "_automergeDocs", null);
3249
+ _ts_decorate9([
3250
+ trace6.info({
3251
+ depth: null
3252
+ })
3253
+ ], AutomergeHost.prototype, "_automergePeers", null);
3254
+ AutomergeHost = _ts_decorate9([
3255
+ trace6.resource()
3256
+ ], AutomergeHost);
3208
3257
 
3209
3258
  export {
3210
3259
  codec,
@@ -3231,7 +3280,9 @@ export {
3231
3280
  AuthStatus,
3232
3281
  SpaceProtocolSession,
3233
3282
  SpaceManager,
3234
- AutomergeHost,
3235
- AutomergeStorageAdapter
3283
+ AutomergeStorageAdapter,
3284
+ LocalHostNetworkAdapter,
3285
+ MeshNetworkAdapter,
3286
+ AutomergeHost
3236
3287
  };
3237
- //# sourceMappingURL=chunk-26G7ZQMP.mjs.map
3288
+ //# sourceMappingURL=chunk-WIB35LJH.mjs.map