@dxos/echo-pipeline 0.4.4-main.fcf0b00 → 0.4.4-next.ac77e71
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.
- package/dist/lib/browser/{chunk-26G7ZQMP.mjs → chunk-WIB35LJH.mjs} +305 -254
- package/dist/lib/browser/{chunk-26G7ZQMP.mjs.map → chunk-WIB35LJH.mjs.map} +4 -4
- package/dist/lib/browser/index.mjs +5 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +1 -1
- package/dist/lib/node/{chunk-V62AY27P.cjs → chunk-37RERU2L.cjs} +295 -248
- package/dist/lib/node/{chunk-V62AY27P.cjs.map → chunk-37RERU2L.cjs.map} +4 -4
- package/dist/lib/node/index.cjs +31 -27
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +16 -16
- package/dist/types/src/automerge/automerge-host.d.ts +5 -31
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-storage-adapter.d.ts +16 -0
- package/dist/types/src/automerge/automerge-storage-adapter.d.ts.map +1 -0
- package/dist/types/src/automerge/index.d.ts +4 -1
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/automerge/local-host-network-adapter.d.ts +23 -0
- package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -0
- package/dist/types/src/automerge/mesh-network-adapter.d.ts +18 -0
- package/dist/types/src/automerge/mesh-network-adapter.d.ts.map +1 -0
- package/package.json +34 -34
- package/src/automerge/automerge-host.test.ts +102 -2
- package/src/automerge/automerge-host.ts +27 -303
- package/src/automerge/automerge-storage-adapter.ts +105 -0
- package/src/automerge/index.ts +4 -1
- package/src/automerge/local-host-network-adapter.ts +109 -0
- 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-
|
|
2767
|
-
import {
|
|
2768
|
-
import {
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
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
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
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
|
-
|
|
2896
|
-
|
|
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
|
|
2899
|
-
this.
|
|
2900
|
-
|
|
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
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
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
|
-
|
|
2909
|
-
|
|
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
|
|
2912
|
-
|
|
2833
|
+
async close() {
|
|
2834
|
+
this._state = "closed";
|
|
2913
2835
|
}
|
|
2914
|
-
|
|
2915
|
-
|
|
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
|
-
|
|
2921
|
-
|
|
2839
|
+
_getKeyFromFilename(filename) {
|
|
2840
|
+
return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
|
|
2922
2841
|
}
|
|
2923
2842
|
};
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
3066
|
-
F:
|
|
3067
|
-
L:
|
|
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:
|
|
3076
|
-
}).catch((err) =>
|
|
3077
|
-
F:
|
|
3078
|
-
L:
|
|
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
|
-
|
|
3087
|
-
F:
|
|
3088
|
-
L:
|
|
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
|
-
|
|
3105
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
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
|
-
|
|
3164
|
-
|
|
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
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
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
|
-
|
|
3188
|
-
|
|
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.
|
|
3210
|
+
this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
|
|
3211
|
+
await this._clientNetwork.close();
|
|
3200
3212
|
}
|
|
3201
|
-
|
|
3202
|
-
|
|
3213
|
+
//
|
|
3214
|
+
// Methods for client-services.
|
|
3215
|
+
//
|
|
3216
|
+
syncRepo(request) {
|
|
3217
|
+
return this._clientNetwork.syncRepo(request);
|
|
3203
3218
|
}
|
|
3204
|
-
|
|
3205
|
-
return
|
|
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
|
-
|
|
3235
|
-
|
|
3283
|
+
AutomergeStorageAdapter,
|
|
3284
|
+
LocalHostNetworkAdapter,
|
|
3285
|
+
MeshNetworkAdapter,
|
|
3286
|
+
AutomergeHost
|
|
3236
3287
|
};
|
|
3237
|
-
//# sourceMappingURL=chunk-
|
|
3288
|
+
//# sourceMappingURL=chunk-WIB35LJH.mjs.map
|