@dxos/echo-pipeline 0.3.11-main.c86e105 → 0.3.11-main.c95bc86
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-44D2XTQP.mjs → chunk-JBCUDOBI.mjs} +139 -23
- package/dist/lib/browser/{chunk-44D2XTQP.mjs.map → chunk-JBCUDOBI.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +1 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +2 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-PZONK23P.cjs → chunk-7E5PNIXR.cjs} +137 -25
- package/dist/lib/node/{chunk-PZONK23P.cjs.map → chunk-7E5PNIXR.cjs.map} +3 -3
- package/dist/lib/node/index.cjs +26 -28
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +17 -17
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/automerge/automerge-host.d.ts +24 -2
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/index.d.ts +1 -1
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +2 -2
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/package.json +33 -33
- package/src/automerge/automerge-host.test.ts +291 -34
- package/src/automerge/automerge-host.ts +105 -16
- package/src/automerge/index.ts +1 -1
- package/src/space/space-manager.ts +3 -3
- package/src/testing/test-agent-builder.ts +1 -1
|
@@ -2685,7 +2685,7 @@ var SpaceManager = class {
|
|
|
2685
2685
|
...this._spaces.values()
|
|
2686
2686
|
].map((space) => space.close()));
|
|
2687
2687
|
}
|
|
2688
|
-
async constructSpace({ metadata, swarmIdentity,
|
|
2688
|
+
async constructSpace({ metadata, swarmIdentity, onAuthorizedConnection, onAuthFailure, memberKey }) {
|
|
2689
2689
|
log12.trace("dxos.echo.space-manager.construct-space", trace4.begin({
|
|
2690
2690
|
id: this._instanceId
|
|
2691
2691
|
}), {
|
|
@@ -2708,7 +2708,7 @@ var SpaceManager = class {
|
|
|
2708
2708
|
topic: spaceKey,
|
|
2709
2709
|
swarmIdentity,
|
|
2710
2710
|
networkManager: this._networkManager,
|
|
2711
|
-
onSessionAuth:
|
|
2711
|
+
onSessionAuth: onAuthorizedConnection,
|
|
2712
2712
|
onAuthFailure,
|
|
2713
2713
|
blobStore: this._blobStore
|
|
2714
2714
|
});
|
|
@@ -2746,28 +2746,96 @@ SpaceManager = _ts_decorate8([
|
|
|
2746
2746
|
], SpaceManager);
|
|
2747
2747
|
|
|
2748
2748
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
2749
|
+
import { Trigger as Trigger2 } from "@dxos/async";
|
|
2749
2750
|
import { Repo, NetworkAdapter, StorageAdapter, cbor } from "@dxos/automerge/automerge-repo";
|
|
2750
2751
|
import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
|
|
2751
2752
|
import { Stream as Stream2 } from "@dxos/codec-protobuf";
|
|
2752
2753
|
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2754
|
+
import { PublicKey as PublicKey8 } from "@dxos/keys";
|
|
2753
2755
|
import { log as log13 } from "@dxos/log";
|
|
2754
2756
|
import { StorageType } from "@dxos/random-access-storage";
|
|
2755
2757
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
2756
|
-
import { arrayToBuffer as arrayToBuffer2, bufferToArray } from "@dxos/util";
|
|
2758
|
+
import { ComplexMap as ComplexMap7, ComplexSet, arrayToBuffer as arrayToBuffer2, bufferToArray, defaultMap } from "@dxos/util";
|
|
2757
2759
|
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
2758
2760
|
var AutomergeHost = class {
|
|
2759
2761
|
constructor(storageDirectory) {
|
|
2762
|
+
/**
|
|
2763
|
+
* spaceKey -> deviceKey[]
|
|
2764
|
+
*/
|
|
2765
|
+
this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
|
|
2760
2766
|
this._meshNetwork = new MeshNetworkAdapter();
|
|
2761
2767
|
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
2762
2768
|
this._storage = storageDirectory.type === StorageType.IDB ? new IndexedDBStorageAdapter(storageDirectory.path, "data") : new AutomergeStorageAdapter(storageDirectory);
|
|
2763
2769
|
this._repo = new Repo({
|
|
2770
|
+
peerId: `host-${PublicKey8.random().toHex()}`,
|
|
2764
2771
|
network: [
|
|
2765
2772
|
this._clientNetwork,
|
|
2766
2773
|
this._meshNetwork
|
|
2767
2774
|
],
|
|
2768
2775
|
storage: this._storage,
|
|
2769
2776
|
// TODO(dmaretskyi): Share based on HALO permissions and space affinity.
|
|
2770
|
-
|
|
2777
|
+
// Hosts, running in the worker, don't share documents unless requested by other peers.
|
|
2778
|
+
sharePolicy: async (peerId, documentId) => {
|
|
2779
|
+
if (peerId.startsWith("client-")) {
|
|
2780
|
+
return true;
|
|
2781
|
+
}
|
|
2782
|
+
if (!documentId) {
|
|
2783
|
+
return false;
|
|
2784
|
+
}
|
|
2785
|
+
const doc = this._repo.handles[documentId]?.docSync();
|
|
2786
|
+
if (!doc) {
|
|
2787
|
+
log13.warn("doc not found for share policy check", {
|
|
2788
|
+
peerId,
|
|
2789
|
+
documentId
|
|
2790
|
+
}, {
|
|
2791
|
+
F: __dxlog_file14,
|
|
2792
|
+
L: 65,
|
|
2793
|
+
S: this,
|
|
2794
|
+
C: (f, a) => f(...a)
|
|
2795
|
+
});
|
|
2796
|
+
return false;
|
|
2797
|
+
}
|
|
2798
|
+
try {
|
|
2799
|
+
const spaceKey = PublicKey8.from(doc.experimental_spaceKey);
|
|
2800
|
+
const authorizedDevices = this._authorizedDevices.get(spaceKey);
|
|
2801
|
+
const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
|
|
2802
|
+
if (!deviceKeyHex) {
|
|
2803
|
+
log13.warn("device key not found for share policy check", {
|
|
2804
|
+
peerId,
|
|
2805
|
+
documentId
|
|
2806
|
+
}, {
|
|
2807
|
+
F: __dxlog_file14,
|
|
2808
|
+
L: 76,
|
|
2809
|
+
S: this,
|
|
2810
|
+
C: (f, a) => f(...a)
|
|
2811
|
+
});
|
|
2812
|
+
return false;
|
|
2813
|
+
}
|
|
2814
|
+
const deviceKey = PublicKey8.from(deviceKeyHex);
|
|
2815
|
+
const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
|
|
2816
|
+
log13.info("share policy check", {
|
|
2817
|
+
peerId,
|
|
2818
|
+
documentId,
|
|
2819
|
+
deviceKey,
|
|
2820
|
+
spaceKey,
|
|
2821
|
+
isAuthorized
|
|
2822
|
+
}, {
|
|
2823
|
+
F: __dxlog_file14,
|
|
2824
|
+
L: 82,
|
|
2825
|
+
S: this,
|
|
2826
|
+
C: (f, a) => f(...a)
|
|
2827
|
+
});
|
|
2828
|
+
return isAuthorized;
|
|
2829
|
+
} catch (err) {
|
|
2830
|
+
log13.catch(err, void 0, {
|
|
2831
|
+
F: __dxlog_file14,
|
|
2832
|
+
L: 85,
|
|
2833
|
+
S: this,
|
|
2834
|
+
C: (f, a) => f(...a)
|
|
2835
|
+
});
|
|
2836
|
+
return false;
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2771
2839
|
});
|
|
2772
2840
|
this._clientNetwork.ready();
|
|
2773
2841
|
this._meshNetwork.ready();
|
|
@@ -2776,6 +2844,7 @@ var AutomergeHost = class {
|
|
|
2776
2844
|
return this._repo;
|
|
2777
2845
|
}
|
|
2778
2846
|
async close() {
|
|
2847
|
+
this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
|
|
2779
2848
|
await this._clientNetwork.close();
|
|
2780
2849
|
}
|
|
2781
2850
|
//
|
|
@@ -2787,7 +2856,7 @@ var AutomergeHost = class {
|
|
|
2787
2856
|
sendSyncMessage(request) {
|
|
2788
2857
|
return this._clientNetwork.sendSyncMessage(request);
|
|
2789
2858
|
}
|
|
2790
|
-
getHostInfo() {
|
|
2859
|
+
async getHostInfo() {
|
|
2791
2860
|
return this._clientNetwork.getHostInfo();
|
|
2792
2861
|
}
|
|
2793
2862
|
//
|
|
@@ -2796,11 +2865,15 @@ var AutomergeHost = class {
|
|
|
2796
2865
|
createExtension() {
|
|
2797
2866
|
return this._meshNetwork.createExtension();
|
|
2798
2867
|
}
|
|
2868
|
+
authorizeDevice(spaceKey, deviceKey) {
|
|
2869
|
+
defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
|
|
2870
|
+
}
|
|
2799
2871
|
};
|
|
2800
2872
|
var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
2801
2873
|
constructor() {
|
|
2802
2874
|
super(...arguments);
|
|
2803
2875
|
this._peers = /* @__PURE__ */ new Map();
|
|
2876
|
+
this._connected = new Trigger2();
|
|
2804
2877
|
}
|
|
2805
2878
|
/**
|
|
2806
2879
|
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
@@ -2812,12 +2885,13 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
2812
2885
|
}
|
|
2813
2886
|
connect(peerId) {
|
|
2814
2887
|
this.peerId = peerId;
|
|
2888
|
+
this._connected.wake();
|
|
2815
2889
|
}
|
|
2816
2890
|
send(message) {
|
|
2817
2891
|
const peer = this._peers.get(message.targetId);
|
|
2818
2892
|
invariant10(peer, "Peer not found.", {
|
|
2819
2893
|
F: __dxlog_file14,
|
|
2820
|
-
L:
|
|
2894
|
+
L: 165,
|
|
2821
2895
|
S: this,
|
|
2822
2896
|
A: [
|
|
2823
2897
|
"peer",
|
|
@@ -2837,7 +2911,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
2837
2911
|
return new Stream2(({ next, close }) => {
|
|
2838
2912
|
invariant10(!this._peers.has(peerId), "Peer already connected.", {
|
|
2839
2913
|
F: __dxlog_file14,
|
|
2840
|
-
L:
|
|
2914
|
+
L: 183,
|
|
2841
2915
|
S: this,
|
|
2842
2916
|
A: [
|
|
2843
2917
|
"!this._peers.has(peerId)",
|
|
@@ -2859,19 +2933,35 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
2859
2933
|
});
|
|
2860
2934
|
}
|
|
2861
2935
|
});
|
|
2862
|
-
this.
|
|
2863
|
-
|
|
2864
|
-
})
|
|
2936
|
+
this._connected.wait({
|
|
2937
|
+
timeout: 1e3
|
|
2938
|
+
}).then(() => {
|
|
2939
|
+
this.emit("peer-candidate", {
|
|
2940
|
+
peerMetadata: {},
|
|
2941
|
+
peerId
|
|
2942
|
+
});
|
|
2943
|
+
}).catch((err) => log13.catch(err, void 0, {
|
|
2944
|
+
F: __dxlog_file14,
|
|
2945
|
+
L: 208,
|
|
2946
|
+
S: this,
|
|
2947
|
+
C: (f, a) => f(...a)
|
|
2948
|
+
}));
|
|
2865
2949
|
});
|
|
2866
2950
|
}
|
|
2867
2951
|
async sendSyncMessage({ id, syncMessage }) {
|
|
2952
|
+
await this._connected.wait({
|
|
2953
|
+
timeout: 1e3
|
|
2954
|
+
});
|
|
2868
2955
|
const message = cbor.decode(syncMessage);
|
|
2869
2956
|
this.emit("message", message);
|
|
2870
2957
|
}
|
|
2871
|
-
getHostInfo() {
|
|
2958
|
+
async getHostInfo() {
|
|
2959
|
+
await this._connected.wait({
|
|
2960
|
+
timeout: 1e3
|
|
2961
|
+
});
|
|
2872
2962
|
invariant10(this.peerId, "Peer id not set.", {
|
|
2873
2963
|
F: __dxlog_file14,
|
|
2874
|
-
L:
|
|
2964
|
+
L: 220,
|
|
2875
2965
|
S: this,
|
|
2876
2966
|
A: [
|
|
2877
2967
|
"this.peerId",
|
|
@@ -2907,7 +2997,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
|
|
|
2907
2997
|
const extension = this._extensions.get(receiverId);
|
|
2908
2998
|
invariant10(extension, "Extension not found.", {
|
|
2909
2999
|
F: __dxlog_file14,
|
|
2910
|
-
L:
|
|
3000
|
+
L: 255,
|
|
2911
3001
|
S: this,
|
|
2912
3002
|
A: [
|
|
2913
3003
|
"extension",
|
|
@@ -2918,7 +3008,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
|
|
|
2918
3008
|
payload: cbor.encode(message)
|
|
2919
3009
|
}).catch((err) => log13.catch(err, void 0, {
|
|
2920
3010
|
F: __dxlog_file14,
|
|
2921
|
-
L:
|
|
3011
|
+
L: 256,
|
|
2922
3012
|
S: this,
|
|
2923
3013
|
C: (f, a) => f(...a)
|
|
2924
3014
|
}));
|
|
@@ -2928,7 +3018,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
|
|
|
2928
3018
|
createExtension() {
|
|
2929
3019
|
invariant10(this.peerId, "Peer id not set.", {
|
|
2930
3020
|
F: __dxlog_file14,
|
|
2931
|
-
L:
|
|
3021
|
+
L: 264,
|
|
2932
3022
|
S: this,
|
|
2933
3023
|
A: [
|
|
2934
3024
|
"this.peerId",
|
|
@@ -2939,13 +3029,17 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
|
|
|
2939
3029
|
const extension = new AutomergeReplicator({
|
|
2940
3030
|
peerId: this.peerId
|
|
2941
3031
|
}, {
|
|
2942
|
-
onStartReplication: async (info) => {
|
|
3032
|
+
onStartReplication: async (info, remotePeerId) => {
|
|
2943
3033
|
if (this._extensions.has(info.id)) {
|
|
2944
3034
|
return;
|
|
2945
3035
|
}
|
|
2946
3036
|
peerInfo = info;
|
|
2947
3037
|
this._extensions.set(info.id, extension);
|
|
2948
3038
|
this.emit("peer-candidate", {
|
|
3039
|
+
// TODO(mykola): Hack, stop abusing `peerMetadata` field.
|
|
3040
|
+
peerMetadata: {
|
|
3041
|
+
dxos_deviceKey: remotePeerId.toHex()
|
|
3042
|
+
},
|
|
2949
3043
|
peerId: info.id
|
|
2950
3044
|
});
|
|
2951
3045
|
},
|
|
@@ -2954,9 +3048,13 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
|
|
|
2954
3048
|
this.emit("message", message);
|
|
2955
3049
|
},
|
|
2956
3050
|
onClose: async () => {
|
|
2957
|
-
|
|
3051
|
+
if (!peerInfo) {
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
this.emit("peer-disconnected", {
|
|
2958
3055
|
peerId: peerInfo.id
|
|
2959
3056
|
});
|
|
3057
|
+
this._extensions.delete(peerInfo.id);
|
|
2960
3058
|
}
|
|
2961
3059
|
});
|
|
2962
3060
|
return extension;
|
|
@@ -2966,8 +3064,12 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
|
|
|
2966
3064
|
constructor(_directory) {
|
|
2967
3065
|
super();
|
|
2968
3066
|
this._directory = _directory;
|
|
3067
|
+
this._state = "opened";
|
|
2969
3068
|
}
|
|
2970
3069
|
async load(key) {
|
|
3070
|
+
if (this._state !== "opened") {
|
|
3071
|
+
return void 0;
|
|
3072
|
+
}
|
|
2971
3073
|
const filename = this._getFilename(key);
|
|
2972
3074
|
const file = this._directory.getOrCreateFile(filename);
|
|
2973
3075
|
const { size } = await file.stat();
|
|
@@ -2978,6 +3080,9 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
|
|
|
2978
3080
|
return bufferToArray(buffer);
|
|
2979
3081
|
}
|
|
2980
3082
|
async save(key, data) {
|
|
3083
|
+
if (this._state !== "opened") {
|
|
3084
|
+
return void 0;
|
|
3085
|
+
}
|
|
2981
3086
|
const filename = this._getFilename(key);
|
|
2982
3087
|
const file = this._directory.getOrCreateFile(filename);
|
|
2983
3088
|
await file.write(0, arrayToBuffer2(data));
|
|
@@ -2985,11 +3090,17 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
|
|
|
2985
3090
|
await file.flush?.();
|
|
2986
3091
|
}
|
|
2987
3092
|
async remove(key) {
|
|
3093
|
+
if (this._state !== "opened") {
|
|
3094
|
+
return void 0;
|
|
3095
|
+
}
|
|
2988
3096
|
const filename = this._getFilename(key);
|
|
2989
3097
|
const file = this._directory.getOrCreateFile(filename);
|
|
2990
|
-
await file.
|
|
3098
|
+
await file.destroy();
|
|
2991
3099
|
}
|
|
2992
3100
|
async loadRange(keyPrefix) {
|
|
3101
|
+
if (this._state !== "opened") {
|
|
3102
|
+
return [];
|
|
3103
|
+
}
|
|
2993
3104
|
const filename = this._getFilename(keyPrefix);
|
|
2994
3105
|
const entries = await this._directory.list();
|
|
2995
3106
|
return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
@@ -3003,13 +3114,19 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
|
|
|
3003
3114
|
}));
|
|
3004
3115
|
}
|
|
3005
3116
|
async removeRange(keyPrefix) {
|
|
3117
|
+
if (this._state !== "opened") {
|
|
3118
|
+
return void 0;
|
|
3119
|
+
}
|
|
3006
3120
|
const filename = this._getFilename(keyPrefix);
|
|
3007
3121
|
const entries = await this._directory.list();
|
|
3008
3122
|
await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
3009
|
-
const file = this._directory.getOrCreateFile(
|
|
3010
|
-
await file.
|
|
3123
|
+
const file = this._directory.getOrCreateFile(entry);
|
|
3124
|
+
await file.destroy();
|
|
3011
3125
|
}));
|
|
3012
3126
|
}
|
|
3127
|
+
async close() {
|
|
3128
|
+
this._state = "closed";
|
|
3129
|
+
}
|
|
3013
3130
|
_getFilename(key) {
|
|
3014
3131
|
return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
|
|
3015
3132
|
}
|
|
@@ -3043,7 +3160,6 @@ export {
|
|
|
3043
3160
|
AuthStatus,
|
|
3044
3161
|
SpaceProtocolSession,
|
|
3045
3162
|
SpaceManager,
|
|
3046
|
-
AutomergeHost
|
|
3047
|
-
AutomergeStorageAdapter
|
|
3163
|
+
AutomergeHost
|
|
3048
3164
|
};
|
|
3049
|
-
//# sourceMappingURL=chunk-
|
|
3165
|
+
//# sourceMappingURL=chunk-JBCUDOBI.mjs.map
|