@dxos/echo-pipeline 0.4.8-next.2e7285f → 0.4.8
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-3PPSCHNN.mjs → chunk-WAN2XUWE.mjs} +17 -652
- package/dist/lib/browser/{chunk-3PPSCHNN.mjs.map → chunk-WAN2XUWE.mjs.map} +4 -4
- package/dist/lib/browser/index.mjs +633 -6
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +2 -274
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node/{chunk-EVKDEZDX.cjs → chunk-U6J2HC4T.cjs} +19 -644
- package/dist/lib/node/chunk-U6J2HC4T.cjs.map +7 -0
- package/dist/lib/node/index.cjs +647 -30
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +12 -282
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +0 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/util.d.ts +2 -6
- package/dist/types/src/testing/util.d.ts.map +1 -1
- package/package.json +33 -33
- package/src/space/control-pipeline.ts +3 -1
- package/src/testing/index.ts +0 -1
- package/src/testing/util.ts +2 -26
- package/dist/lib/node/chunk-EVKDEZDX.cjs.map +0 -7
- package/dist/types/src/testing/database-test-rig.d.ts +0 -67
- package/dist/types/src/testing/database-test-rig.d.ts.map +0 -1
- package/dist/types/src/tests/database.test.d.ts +0 -2
- package/dist/types/src/tests/database.test.d.ts.map +0 -1
- package/src/testing/database-test-rig.ts +0 -289
- package/src/tests/database.test.ts +0 -100
|
@@ -1987,11 +1987,13 @@ var ControlPipeline = class {
|
|
|
1987
1987
|
queueMicrotask(async () => {
|
|
1988
1988
|
try {
|
|
1989
1989
|
const feed = await feedProvider(info.key);
|
|
1990
|
-
|
|
1990
|
+
if (!this._pipeline.hasFeed(feed.key)) {
|
|
1991
|
+
await this._pipeline.addFeed(feed);
|
|
1992
|
+
}
|
|
1991
1993
|
} catch (err) {
|
|
1992
1994
|
log9.catch(err, void 0, {
|
|
1993
1995
|
F: __dxlog_file10,
|
|
1994
|
-
L:
|
|
1996
|
+
L: 85,
|
|
1995
1997
|
S: this,
|
|
1996
1998
|
C: (f, a) => f(...a)
|
|
1997
1999
|
});
|
|
@@ -2021,7 +2023,7 @@ var ControlPipeline = class {
|
|
|
2021
2023
|
tf: snapshot?.timeframe
|
|
2022
2024
|
}, {
|
|
2023
2025
|
F: __dxlog_file10,
|
|
2024
|
-
L:
|
|
2026
|
+
L: 113,
|
|
2025
2027
|
S: this,
|
|
2026
2028
|
C: (f, a) => f(...a)
|
|
2027
2029
|
});
|
|
@@ -2030,7 +2032,7 @@ var ControlPipeline = class {
|
|
|
2030
2032
|
}
|
|
2031
2033
|
log9("starting...", void 0, {
|
|
2032
2034
|
F: __dxlog_file10,
|
|
2033
|
-
L:
|
|
2035
|
+
L: 118,
|
|
2034
2036
|
S: this,
|
|
2035
2037
|
C: (f, a) => f(...a)
|
|
2036
2038
|
});
|
|
@@ -2040,7 +2042,7 @@ var ControlPipeline = class {
|
|
|
2040
2042
|
await this._pipeline.start();
|
|
2041
2043
|
log9("started", void 0, {
|
|
2042
2044
|
F: __dxlog_file10,
|
|
2043
|
-
L:
|
|
2045
|
+
L: 124,
|
|
2044
2046
|
S: this,
|
|
2045
2047
|
C: (f, a) => f(...a)
|
|
2046
2048
|
});
|
|
@@ -2057,7 +2059,7 @@ var ControlPipeline = class {
|
|
|
2057
2059
|
message
|
|
2058
2060
|
}, {
|
|
2059
2061
|
F: __dxlog_file10,
|
|
2060
|
-
L:
|
|
2062
|
+
L: 137,
|
|
2061
2063
|
S: this,
|
|
2062
2064
|
C: (f, a) => f(...a)
|
|
2063
2065
|
});
|
|
@@ -2079,7 +2081,7 @@ var ControlPipeline = class {
|
|
|
2079
2081
|
snapshot
|
|
2080
2082
|
}, {
|
|
2081
2083
|
F: __dxlog_file10,
|
|
2082
|
-
L:
|
|
2084
|
+
L: 153,
|
|
2083
2085
|
S: this,
|
|
2084
2086
|
C: (f, a) => f(...a)
|
|
2085
2087
|
});
|
|
@@ -2094,7 +2096,7 @@ var ControlPipeline = class {
|
|
|
2094
2096
|
} catch (err) {
|
|
2095
2097
|
log9.catch(err, void 0, {
|
|
2096
2098
|
F: __dxlog_file10,
|
|
2097
|
-
L:
|
|
2099
|
+
L: 166,
|
|
2098
2100
|
S: this,
|
|
2099
2101
|
C: (f, a) => f(...a)
|
|
2100
2102
|
});
|
|
@@ -2108,7 +2110,7 @@ var ControlPipeline = class {
|
|
|
2108
2110
|
seq: msg.seq
|
|
2109
2111
|
}, {
|
|
2110
2112
|
F: __dxlog_file10,
|
|
2111
|
-
L:
|
|
2113
|
+
L: 176,
|
|
2112
2114
|
S: this,
|
|
2113
2115
|
C: (f, a) => f(...a)
|
|
2114
2116
|
});
|
|
@@ -2123,7 +2125,7 @@ var ControlPipeline = class {
|
|
|
2123
2125
|
msg
|
|
2124
2126
|
}, {
|
|
2125
2127
|
F: __dxlog_file10,
|
|
2126
|
-
L:
|
|
2128
|
+
L: 185,
|
|
2127
2129
|
S: this,
|
|
2128
2130
|
C: (f, a) => f(...a)
|
|
2129
2131
|
});
|
|
@@ -2142,7 +2144,7 @@ var ControlPipeline = class {
|
|
|
2142
2144
|
async stop() {
|
|
2143
2145
|
log9("stopping...", void 0, {
|
|
2144
2146
|
F: __dxlog_file10,
|
|
2145
|
-
L:
|
|
2147
|
+
L: 205,
|
|
2146
2148
|
S: this,
|
|
2147
2149
|
C: (f, a) => f(...a)
|
|
2148
2150
|
});
|
|
@@ -2151,7 +2153,7 @@ var ControlPipeline = class {
|
|
|
2151
2153
|
await this._saveTargetTimeframe(this._pipeline.state.timeframe);
|
|
2152
2154
|
log9("stopped", void 0, {
|
|
2153
2155
|
F: __dxlog_file10,
|
|
2154
|
-
L:
|
|
2156
|
+
L: 209,
|
|
2155
2157
|
S: this,
|
|
2156
2158
|
C: (f, a) => f(...a)
|
|
2157
2159
|
});
|
|
@@ -2164,7 +2166,7 @@ var ControlPipeline = class {
|
|
|
2164
2166
|
} catch (err) {
|
|
2165
2167
|
log9(err, void 0, {
|
|
2166
2168
|
F: __dxlog_file10,
|
|
2167
|
-
L:
|
|
2169
|
+
L: 218,
|
|
2168
2170
|
S: this,
|
|
2169
2171
|
C: (f, a) => f(...a)
|
|
2170
2172
|
});
|
|
@@ -2767,638 +2769,6 @@ SpaceManager = _ts_decorate8([
|
|
|
2767
2769
|
trackLeaks4("open", "close")
|
|
2768
2770
|
], SpaceManager);
|
|
2769
2771
|
|
|
2770
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
|
|
2771
|
-
import { arrayToBuffer as arrayToBuffer2, bufferToArray } from "@dxos/util";
|
|
2772
|
-
var AutomergeStorageAdapter = class {
|
|
2773
|
-
constructor(_directory) {
|
|
2774
|
-
this._directory = _directory;
|
|
2775
|
-
this._state = "opened";
|
|
2776
|
-
}
|
|
2777
|
-
async load(key) {
|
|
2778
|
-
if (this._state !== "opened") {
|
|
2779
|
-
return void 0;
|
|
2780
|
-
}
|
|
2781
|
-
const filename = this._getFilename(key);
|
|
2782
|
-
const file = this._directory.getOrCreateFile(filename);
|
|
2783
|
-
const { size } = await file.stat();
|
|
2784
|
-
if (!size || size === 0) {
|
|
2785
|
-
return void 0;
|
|
2786
|
-
}
|
|
2787
|
-
const buffer = await file.read(0, size);
|
|
2788
|
-
return bufferToArray(buffer);
|
|
2789
|
-
}
|
|
2790
|
-
async save(key, data) {
|
|
2791
|
-
if (this._state !== "opened") {
|
|
2792
|
-
return void 0;
|
|
2793
|
-
}
|
|
2794
|
-
const filename = this._getFilename(key);
|
|
2795
|
-
const file = this._directory.getOrCreateFile(filename);
|
|
2796
|
-
await file.write(0, arrayToBuffer2(data));
|
|
2797
|
-
await file.truncate?.(data.length);
|
|
2798
|
-
await file.flush?.();
|
|
2799
|
-
}
|
|
2800
|
-
async remove(key) {
|
|
2801
|
-
if (this._state !== "opened") {
|
|
2802
|
-
return void 0;
|
|
2803
|
-
}
|
|
2804
|
-
const filename = this._getFilename(key);
|
|
2805
|
-
const file = this._directory.getOrCreateFile(filename);
|
|
2806
|
-
await file.destroy();
|
|
2807
|
-
}
|
|
2808
|
-
async loadRange(keyPrefix) {
|
|
2809
|
-
if (this._state !== "opened") {
|
|
2810
|
-
return [];
|
|
2811
|
-
}
|
|
2812
|
-
const filename = this._getFilename(keyPrefix);
|
|
2813
|
-
const entries = await this._directory.list();
|
|
2814
|
-
return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
2815
|
-
const file = this._directory.getOrCreateFile(entry);
|
|
2816
|
-
const { size } = await file.stat();
|
|
2817
|
-
const buffer = await file.read(0, size);
|
|
2818
|
-
return {
|
|
2819
|
-
key: this._getKeyFromFilename(entry),
|
|
2820
|
-
data: bufferToArray(buffer)
|
|
2821
|
-
};
|
|
2822
|
-
}));
|
|
2823
|
-
}
|
|
2824
|
-
async removeRange(keyPrefix) {
|
|
2825
|
-
if (this._state !== "opened") {
|
|
2826
|
-
return void 0;
|
|
2827
|
-
}
|
|
2828
|
-
const filename = this._getFilename(keyPrefix);
|
|
2829
|
-
const entries = await this._directory.list();
|
|
2830
|
-
await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
2831
|
-
const file = this._directory.getOrCreateFile(entry);
|
|
2832
|
-
await file.destroy();
|
|
2833
|
-
}));
|
|
2834
|
-
}
|
|
2835
|
-
async close() {
|
|
2836
|
-
this._state = "closed";
|
|
2837
|
-
}
|
|
2838
|
-
_getFilename(key) {
|
|
2839
|
-
return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
|
|
2840
|
-
}
|
|
2841
|
-
_getKeyFromFilename(filename) {
|
|
2842
|
-
return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
|
|
2843
|
-
}
|
|
2844
|
-
};
|
|
2845
|
-
|
|
2846
|
-
// packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
|
|
2847
|
-
import { Trigger as Trigger2 } from "@dxos/async";
|
|
2848
|
-
import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
|
|
2849
|
-
import { Stream as Stream2 } from "@dxos/codec-protobuf";
|
|
2850
|
-
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2851
|
-
import { log as log13 } from "@dxos/log";
|
|
2852
|
-
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
|
|
2853
|
-
var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
2854
|
-
constructor() {
|
|
2855
|
-
super(...arguments);
|
|
2856
|
-
this._peers = /* @__PURE__ */ new Map();
|
|
2857
|
-
this._connected = new Trigger2();
|
|
2858
|
-
}
|
|
2859
|
-
/**
|
|
2860
|
-
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
2861
|
-
*/
|
|
2862
|
-
ready() {
|
|
2863
|
-
this.emit("ready", {
|
|
2864
|
-
network: this
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
connect(peerId) {
|
|
2868
|
-
this.peerId = peerId;
|
|
2869
|
-
this._connected.wake();
|
|
2870
|
-
}
|
|
2871
|
-
send(message) {
|
|
2872
|
-
const peer = this._peers.get(message.targetId);
|
|
2873
|
-
invariant10(peer, "Peer not found.", {
|
|
2874
|
-
F: __dxlog_file14,
|
|
2875
|
-
L: 45,
|
|
2876
|
-
S: this,
|
|
2877
|
-
A: [
|
|
2878
|
-
"peer",
|
|
2879
|
-
"'Peer not found.'"
|
|
2880
|
-
]
|
|
2881
|
-
});
|
|
2882
|
-
peer.send(message);
|
|
2883
|
-
}
|
|
2884
|
-
async close() {
|
|
2885
|
-
this._peers.forEach((peer) => peer.disconnect());
|
|
2886
|
-
this.emit("close");
|
|
2887
|
-
}
|
|
2888
|
-
disconnect() {
|
|
2889
|
-
}
|
|
2890
|
-
syncRepo({ id, syncMessage }) {
|
|
2891
|
-
const peerId = this._getPeerId(id);
|
|
2892
|
-
return new Stream2(({ next, close }) => {
|
|
2893
|
-
invariant10(!this._peers.has(peerId), "Peer already connected.", {
|
|
2894
|
-
F: __dxlog_file14,
|
|
2895
|
-
L: 63,
|
|
2896
|
-
S: this,
|
|
2897
|
-
A: [
|
|
2898
|
-
"!this._peers.has(peerId)",
|
|
2899
|
-
"'Peer already connected.'"
|
|
2900
|
-
]
|
|
2901
|
-
});
|
|
2902
|
-
this._peers.set(peerId, {
|
|
2903
|
-
connected: true,
|
|
2904
|
-
send: (message) => {
|
|
2905
|
-
next({
|
|
2906
|
-
syncMessage: cbor.encode(message)
|
|
2907
|
-
});
|
|
2908
|
-
},
|
|
2909
|
-
disconnect: () => {
|
|
2910
|
-
this._peers.delete(peerId);
|
|
2911
|
-
close();
|
|
2912
|
-
this.emit("peer-disconnected", {
|
|
2913
|
-
peerId
|
|
2914
|
-
});
|
|
2915
|
-
}
|
|
2916
|
-
});
|
|
2917
|
-
this._connected.wait({
|
|
2918
|
-
timeout: 1e3
|
|
2919
|
-
}).then(() => {
|
|
2920
|
-
this.emit("peer-candidate", {
|
|
2921
|
-
peerMetadata: {},
|
|
2922
|
-
peerId
|
|
2923
|
-
});
|
|
2924
|
-
}).catch((err) => log13.catch(err, void 0, {
|
|
2925
|
-
F: __dxlog_file14,
|
|
2926
|
-
L: 88,
|
|
2927
|
-
S: this,
|
|
2928
|
-
C: (f, a) => f(...a)
|
|
2929
|
-
}));
|
|
2930
|
-
});
|
|
2931
|
-
}
|
|
2932
|
-
async sendSyncMessage({ id, syncMessage }) {
|
|
2933
|
-
await this._connected.wait({
|
|
2934
|
-
timeout: 1e3
|
|
2935
|
-
});
|
|
2936
|
-
const message = cbor.decode(syncMessage);
|
|
2937
|
-
this.emit("message", message);
|
|
2938
|
-
}
|
|
2939
|
-
async getHostInfo() {
|
|
2940
|
-
await this._connected.wait({
|
|
2941
|
-
timeout: 1e3
|
|
2942
|
-
});
|
|
2943
|
-
invariant10(this.peerId, "Peer id not set.", {
|
|
2944
|
-
F: __dxlog_file14,
|
|
2945
|
-
L: 100,
|
|
2946
|
-
S: this,
|
|
2947
|
-
A: [
|
|
2948
|
-
"this.peerId",
|
|
2949
|
-
"'Peer id not set.'"
|
|
2950
|
-
]
|
|
2951
|
-
});
|
|
2952
|
-
return {
|
|
2953
|
-
peerId: this.peerId
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
|
-
_getPeerId(id) {
|
|
2957
|
-
return id;
|
|
2958
|
-
}
|
|
2959
|
-
};
|
|
2960
|
-
|
|
2961
|
-
// packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
|
|
2962
|
-
import { Trigger as Trigger3 } from "@dxos/async";
|
|
2963
|
-
import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
2964
|
-
import { invariant as invariant11 } from "@dxos/invariant";
|
|
2965
|
-
import { log as log14 } from "@dxos/log";
|
|
2966
|
-
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
2967
|
-
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
|
|
2968
|
-
var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
2969
|
-
constructor() {
|
|
2970
|
-
super(...arguments);
|
|
2971
|
-
this._extensions = /* @__PURE__ */ new Map();
|
|
2972
|
-
this._connected = new Trigger3();
|
|
2973
|
-
}
|
|
2974
|
-
/**
|
|
2975
|
-
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
2976
|
-
*/
|
|
2977
|
-
ready() {
|
|
2978
|
-
this.emit("ready", {
|
|
2979
|
-
network: this
|
|
2980
|
-
});
|
|
2981
|
-
}
|
|
2982
|
-
connect(peerId) {
|
|
2983
|
-
this.peerId = peerId;
|
|
2984
|
-
this._connected.wake();
|
|
2985
|
-
}
|
|
2986
|
-
send(message) {
|
|
2987
|
-
const receiverId = message.targetId;
|
|
2988
|
-
const extension = this._extensions.get(receiverId);
|
|
2989
|
-
invariant11(extension, "Extension not found.", {
|
|
2990
|
-
F: __dxlog_file15,
|
|
2991
|
-
L: 38,
|
|
2992
|
-
S: this,
|
|
2993
|
-
A: [
|
|
2994
|
-
"extension",
|
|
2995
|
-
"'Extension not found.'"
|
|
2996
|
-
]
|
|
2997
|
-
});
|
|
2998
|
-
extension.sendSyncMessage({
|
|
2999
|
-
payload: cbor2.encode(message)
|
|
3000
|
-
}).catch((err) => log14.catch(err, void 0, {
|
|
3001
|
-
F: __dxlog_file15,
|
|
3002
|
-
L: 39,
|
|
3003
|
-
S: this,
|
|
3004
|
-
C: (f, a) => f(...a)
|
|
3005
|
-
}));
|
|
3006
|
-
}
|
|
3007
|
-
disconnect() {
|
|
3008
|
-
}
|
|
3009
|
-
createExtension() {
|
|
3010
|
-
invariant11(this.peerId, "Peer id not set.", {
|
|
3011
|
-
F: __dxlog_file15,
|
|
3012
|
-
L: 47,
|
|
3013
|
-
S: this,
|
|
3014
|
-
A: [
|
|
3015
|
-
"this.peerId",
|
|
3016
|
-
"'Peer id not set.'"
|
|
3017
|
-
]
|
|
3018
|
-
});
|
|
3019
|
-
let peerInfo;
|
|
3020
|
-
const extension = new AutomergeReplicator({
|
|
3021
|
-
peerId: this.peerId
|
|
3022
|
-
}, {
|
|
3023
|
-
onStartReplication: async (info, remotePeerId) => {
|
|
3024
|
-
await this._connected.wait();
|
|
3025
|
-
log14("onStartReplication", {
|
|
3026
|
-
id: info.id,
|
|
3027
|
-
thisPeerId: this.peerId,
|
|
3028
|
-
remotePeerId: remotePeerId.toHex()
|
|
3029
|
-
}, {
|
|
3030
|
-
F: __dxlog_file15,
|
|
3031
|
-
L: 70,
|
|
3032
|
-
S: this,
|
|
3033
|
-
C: (f, a) => f(...a)
|
|
3034
|
-
});
|
|
3035
|
-
if (!this._extensions.has(info.id)) {
|
|
3036
|
-
peerInfo = info;
|
|
3037
|
-
this._extensions.set(info.id, extension);
|
|
3038
|
-
log14("peer-candidate", {
|
|
3039
|
-
id: info.id,
|
|
3040
|
-
thisPeerId: this.peerId,
|
|
3041
|
-
remotePeerId: remotePeerId.toHex()
|
|
3042
|
-
}, {
|
|
3043
|
-
F: __dxlog_file15,
|
|
3044
|
-
L: 76,
|
|
3045
|
-
S: this,
|
|
3046
|
-
C: (f, a) => f(...a)
|
|
3047
|
-
});
|
|
3048
|
-
this.emit("peer-candidate", {
|
|
3049
|
-
// TODO(mykola): Hack, stop abusing `peerMetadata` field.
|
|
3050
|
-
peerMetadata: {
|
|
3051
|
-
dxos_deviceKey: remotePeerId.toHex()
|
|
3052
|
-
},
|
|
3053
|
-
peerId: info.id
|
|
3054
|
-
});
|
|
3055
|
-
}
|
|
3056
|
-
},
|
|
3057
|
-
onSyncMessage: async ({ payload }) => {
|
|
3058
|
-
if (!peerInfo) {
|
|
3059
|
-
return;
|
|
3060
|
-
}
|
|
3061
|
-
const message = cbor2.decode(payload);
|
|
3062
|
-
this.emit("message", message);
|
|
3063
|
-
},
|
|
3064
|
-
onClose: async () => {
|
|
3065
|
-
if (!peerInfo) {
|
|
3066
|
-
return;
|
|
3067
|
-
}
|
|
3068
|
-
this.emit("peer-disconnected", {
|
|
3069
|
-
peerId: peerInfo.id
|
|
3070
|
-
});
|
|
3071
|
-
this._extensions.delete(peerInfo.id);
|
|
3072
|
-
}
|
|
3073
|
-
});
|
|
3074
|
-
return extension;
|
|
3075
|
-
}
|
|
3076
|
-
};
|
|
3077
|
-
|
|
3078
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
3079
|
-
import { next as automerge, getHeads } from "@dxos/automerge/automerge";
|
|
3080
|
-
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
3081
|
-
import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
|
|
3082
|
-
import { Context as Context7 } from "@dxos/context";
|
|
3083
|
-
import { PublicKey as PublicKey8 } from "@dxos/keys";
|
|
3084
|
-
import { log as log15 } from "@dxos/log";
|
|
3085
|
-
import { idCodec } from "@dxos/protocols";
|
|
3086
|
-
import { StorageType } from "@dxos/random-access-storage";
|
|
3087
|
-
import { trace as trace6 } from "@dxos/tracing";
|
|
3088
|
-
import { ComplexMap as ComplexMap7, ComplexSet, defaultMap, mapValues } from "@dxos/util";
|
|
3089
|
-
|
|
3090
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-storage–wrapper.ts
|
|
3091
|
-
var AutomergeStorageWrapper = class {
|
|
3092
|
-
constructor({ storage, callbacks }) {
|
|
3093
|
-
this._storage = storage;
|
|
3094
|
-
this._callbacks = callbacks;
|
|
3095
|
-
}
|
|
3096
|
-
async load(key) {
|
|
3097
|
-
return this._storage.load(key);
|
|
3098
|
-
}
|
|
3099
|
-
async save(key, value) {
|
|
3100
|
-
await this._callbacks.beforeSave?.(key);
|
|
3101
|
-
await this._storage.save(key, value);
|
|
3102
|
-
await this._callbacks.afterSave?.(key);
|
|
3103
|
-
}
|
|
3104
|
-
async remove(key) {
|
|
3105
|
-
return this._storage.remove(key);
|
|
3106
|
-
}
|
|
3107
|
-
async loadRange(keyPrefix) {
|
|
3108
|
-
return this._storage.loadRange(keyPrefix);
|
|
3109
|
-
}
|
|
3110
|
-
async removeRange(keyPrefix) {
|
|
3111
|
-
return this._storage.removeRange(keyPrefix);
|
|
3112
|
-
}
|
|
3113
|
-
async close() {
|
|
3114
|
-
if (this._storage instanceof AutomergeStorageAdapter) {
|
|
3115
|
-
return this._storage.close();
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
};
|
|
3119
|
-
|
|
3120
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
3121
|
-
function _ts_decorate9(decorators, target, key, desc) {
|
|
3122
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3123
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
3124
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
3125
|
-
else
|
|
3126
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
3127
|
-
if (d = decorators[i])
|
|
3128
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3129
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3130
|
-
}
|
|
3131
|
-
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
3132
|
-
var AutomergeHost = class {
|
|
3133
|
-
constructor({ directory, metadata }) {
|
|
3134
|
-
this._ctx = new Context7();
|
|
3135
|
-
/**
|
|
3136
|
-
* spaceKey -> deviceKey[]
|
|
3137
|
-
*/
|
|
3138
|
-
this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
|
|
3139
|
-
this._updatingMetadata = /* @__PURE__ */ new Map();
|
|
3140
|
-
this._requestedDocs = /* @__PURE__ */ new Set();
|
|
3141
|
-
this._metadata = metadata;
|
|
3142
|
-
this._meshNetwork = new MeshNetworkAdapter();
|
|
3143
|
-
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
3144
|
-
this._storage = new AutomergeStorageWrapper({
|
|
3145
|
-
storage: (
|
|
3146
|
-
// TODO(mykola): Delete specific handling of IDB storage.
|
|
3147
|
-
directory.type === StorageType.IDB ? new IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory)
|
|
3148
|
-
),
|
|
3149
|
-
callbacks: {
|
|
3150
|
-
beforeSave: (params) => this._beforeSave(params)
|
|
3151
|
-
}
|
|
3152
|
-
});
|
|
3153
|
-
this._peerId = `host-${PublicKey8.random().toHex()}`;
|
|
3154
|
-
this._repo = new Repo({
|
|
3155
|
-
peerId: this._peerId,
|
|
3156
|
-
network: [
|
|
3157
|
-
this._clientNetwork,
|
|
3158
|
-
this._meshNetwork
|
|
3159
|
-
],
|
|
3160
|
-
storage: this._storage,
|
|
3161
|
-
// TODO(dmaretskyi): Share based on HALO permissions and space affinity.
|
|
3162
|
-
// Hosts, running in the worker, don't share documents unless requested by other peers.
|
|
3163
|
-
sharePolicy: async (peerId, documentId) => {
|
|
3164
|
-
if (peerId.startsWith("client-")) {
|
|
3165
|
-
return false;
|
|
3166
|
-
}
|
|
3167
|
-
if (!documentId) {
|
|
3168
|
-
return false;
|
|
3169
|
-
}
|
|
3170
|
-
const doc = this._repo.handles[documentId]?.docSync();
|
|
3171
|
-
if (!doc) {
|
|
3172
|
-
const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
|
|
3173
|
-
log15("doc share policy check", {
|
|
3174
|
-
peerId,
|
|
3175
|
-
documentId,
|
|
3176
|
-
isRequested
|
|
3177
|
-
}, {
|
|
3178
|
-
F: __dxlog_file16,
|
|
3179
|
-
L: 96,
|
|
3180
|
-
S: this,
|
|
3181
|
-
C: (f, a) => f(...a)
|
|
3182
|
-
});
|
|
3183
|
-
return isRequested;
|
|
3184
|
-
}
|
|
3185
|
-
try {
|
|
3186
|
-
const spaceKey = getSpaceKeyFromDoc(doc);
|
|
3187
|
-
if (!spaceKey) {
|
|
3188
|
-
log15("space key not found for share policy check", {
|
|
3189
|
-
peerId,
|
|
3190
|
-
documentId
|
|
3191
|
-
}, {
|
|
3192
|
-
F: __dxlog_file16,
|
|
3193
|
-
L: 103,
|
|
3194
|
-
S: this,
|
|
3195
|
-
C: (f, a) => f(...a)
|
|
3196
|
-
});
|
|
3197
|
-
return false;
|
|
3198
|
-
}
|
|
3199
|
-
const authorizedDevices = this._authorizedDevices.get(PublicKey8.from(spaceKey));
|
|
3200
|
-
const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
|
|
3201
|
-
if (!deviceKeyHex) {
|
|
3202
|
-
log15("device key not found for share policy check", {
|
|
3203
|
-
peerId,
|
|
3204
|
-
documentId
|
|
3205
|
-
}, {
|
|
3206
|
-
F: __dxlog_file16,
|
|
3207
|
-
L: 112,
|
|
3208
|
-
S: this,
|
|
3209
|
-
C: (f, a) => f(...a)
|
|
3210
|
-
});
|
|
3211
|
-
return false;
|
|
3212
|
-
}
|
|
3213
|
-
const deviceKey = PublicKey8.from(deviceKeyHex);
|
|
3214
|
-
const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
|
|
3215
|
-
log15("share policy check", {
|
|
3216
|
-
localPeer: this._peerId,
|
|
3217
|
-
remotePeer: peerId,
|
|
3218
|
-
documentId,
|
|
3219
|
-
deviceKey,
|
|
3220
|
-
spaceKey,
|
|
3221
|
-
isAuthorized
|
|
3222
|
-
}, {
|
|
3223
|
-
F: __dxlog_file16,
|
|
3224
|
-
L: 118,
|
|
3225
|
-
S: this,
|
|
3226
|
-
C: (f, a) => f(...a)
|
|
3227
|
-
});
|
|
3228
|
-
return isAuthorized;
|
|
3229
|
-
} catch (err) {
|
|
3230
|
-
log15.catch(err, void 0, {
|
|
3231
|
-
F: __dxlog_file16,
|
|
3232
|
-
L: 128,
|
|
3233
|
-
S: this,
|
|
3234
|
-
C: (f, a) => f(...a)
|
|
3235
|
-
});
|
|
3236
|
-
return false;
|
|
3237
|
-
}
|
|
3238
|
-
}
|
|
3239
|
-
});
|
|
3240
|
-
this._clientNetwork.ready();
|
|
3241
|
-
this._meshNetwork.ready();
|
|
3242
|
-
{
|
|
3243
|
-
const listener = ({ handle }) => this._onDocument(handle);
|
|
3244
|
-
this._repo.on("document", listener);
|
|
3245
|
-
this._ctx.onDispose(() => {
|
|
3246
|
-
this._repo.off("document", listener);
|
|
3247
|
-
});
|
|
3248
|
-
}
|
|
3249
|
-
}
|
|
3250
|
-
get repo() {
|
|
3251
|
-
return this._repo;
|
|
3252
|
-
}
|
|
3253
|
-
async _beforeSave(path) {
|
|
3254
|
-
const id = path[0];
|
|
3255
|
-
if (this._updatingMetadata.has(id)) {
|
|
3256
|
-
return this._updatingMetadata.get(id);
|
|
3257
|
-
}
|
|
3258
|
-
}
|
|
3259
|
-
_onDocument(handle) {
|
|
3260
|
-
const listener = (event) => this._onUpdate(event);
|
|
3261
|
-
handle.on("change", listener);
|
|
3262
|
-
this._ctx.onDispose(() => {
|
|
3263
|
-
handle.off("change", listener);
|
|
3264
|
-
});
|
|
3265
|
-
}
|
|
3266
|
-
_onUpdate(event) {
|
|
3267
|
-
if (this._metadata == null) {
|
|
3268
|
-
return;
|
|
3269
|
-
}
|
|
3270
|
-
const objectIds = getInlineChanges(event);
|
|
3271
|
-
if (objectIds.length === 0) {
|
|
3272
|
-
return;
|
|
3273
|
-
}
|
|
3274
|
-
const heads = getHeads(event.doc);
|
|
3275
|
-
const lastAvailableHash = heads.at(-1);
|
|
3276
|
-
if (!lastAvailableHash) {
|
|
3277
|
-
return;
|
|
3278
|
-
}
|
|
3279
|
-
const encodedIds = objectIds.map((objectId) => idCodec.encode({
|
|
3280
|
-
documentId: event.handle.documentId,
|
|
3281
|
-
objectId
|
|
3282
|
-
}));
|
|
3283
|
-
const idToLastHash = new Map(encodedIds.map((id) => [
|
|
3284
|
-
id,
|
|
3285
|
-
lastAvailableHash
|
|
3286
|
-
]));
|
|
3287
|
-
const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
|
|
3288
|
-
this._updatingMetadata.delete(event.handle.documentId);
|
|
3289
|
-
}).catch((err) => {
|
|
3290
|
-
this._ctx.disposed && log15.catch(err, void 0, {
|
|
3291
|
-
F: __dxlog_file16,
|
|
3292
|
-
L: 188,
|
|
3293
|
-
S: this,
|
|
3294
|
-
C: (f, a) => f(...a)
|
|
3295
|
-
});
|
|
3296
|
-
});
|
|
3297
|
-
this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
|
|
3298
|
-
}
|
|
3299
|
-
_automergeDocs() {
|
|
3300
|
-
return mapValues(this._repo.handles, (handle) => ({
|
|
3301
|
-
state: handle.state,
|
|
3302
|
-
hasDoc: !!handle.docSync(),
|
|
3303
|
-
heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,
|
|
3304
|
-
data: handle.docSync()?.doc && mapValues(handle.docSync()?.doc, (value, key) => {
|
|
3305
|
-
try {
|
|
3306
|
-
switch (key) {
|
|
3307
|
-
case "access":
|
|
3308
|
-
case "links":
|
|
3309
|
-
return value;
|
|
3310
|
-
case "objects":
|
|
3311
|
-
return Object.keys(value);
|
|
3312
|
-
default:
|
|
3313
|
-
return `${value}`;
|
|
3314
|
-
}
|
|
3315
|
-
} catch (err) {
|
|
3316
|
-
return `${err}`;
|
|
3317
|
-
}
|
|
3318
|
-
})
|
|
3319
|
-
}));
|
|
3320
|
-
}
|
|
3321
|
-
_automergePeers() {
|
|
3322
|
-
return this._repo.peers;
|
|
3323
|
-
}
|
|
3324
|
-
async close() {
|
|
3325
|
-
await this._storage.close();
|
|
3326
|
-
await this._clientNetwork.close();
|
|
3327
|
-
await this._ctx.dispose();
|
|
3328
|
-
}
|
|
3329
|
-
//
|
|
3330
|
-
// Methods for client-services.
|
|
3331
|
-
//
|
|
3332
|
-
syncRepo(request) {
|
|
3333
|
-
return this._clientNetwork.syncRepo(request);
|
|
3334
|
-
}
|
|
3335
|
-
sendSyncMessage(request) {
|
|
3336
|
-
return this._clientNetwork.sendSyncMessage(request);
|
|
3337
|
-
}
|
|
3338
|
-
async getHostInfo() {
|
|
3339
|
-
return this._clientNetwork.getHostInfo();
|
|
3340
|
-
}
|
|
3341
|
-
//
|
|
3342
|
-
// Mesh replication.
|
|
3343
|
-
//
|
|
3344
|
-
createExtension() {
|
|
3345
|
-
return this._meshNetwork.createExtension();
|
|
3346
|
-
}
|
|
3347
|
-
authorizeDevice(spaceKey, deviceKey) {
|
|
3348
|
-
log15("authorizeDevice", {
|
|
3349
|
-
spaceKey,
|
|
3350
|
-
deviceKey
|
|
3351
|
-
}, {
|
|
3352
|
-
F: __dxlog_file16,
|
|
3353
|
-
L: 255,
|
|
3354
|
-
S: this,
|
|
3355
|
-
C: (f, a) => f(...a)
|
|
3356
|
-
});
|
|
3357
|
-
defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
|
|
3358
|
-
}
|
|
3359
|
-
};
|
|
3360
|
-
_ts_decorate9([
|
|
3361
|
-
trace6.info()
|
|
3362
|
-
], AutomergeHost.prototype, "_peerId", void 0);
|
|
3363
|
-
_ts_decorate9([
|
|
3364
|
-
trace6.info({
|
|
3365
|
-
depth: null
|
|
3366
|
-
})
|
|
3367
|
-
], AutomergeHost.prototype, "_automergeDocs", null);
|
|
3368
|
-
_ts_decorate9([
|
|
3369
|
-
trace6.info({
|
|
3370
|
-
depth: null
|
|
3371
|
-
})
|
|
3372
|
-
], AutomergeHost.prototype, "_automergePeers", null);
|
|
3373
|
-
AutomergeHost = _ts_decorate9([
|
|
3374
|
-
trace6.resource()
|
|
3375
|
-
], AutomergeHost);
|
|
3376
|
-
var getInlineChanges = (event) => {
|
|
3377
|
-
const inlineChangedObjectIds = /* @__PURE__ */ new Set();
|
|
3378
|
-
for (const { path } of event.patches) {
|
|
3379
|
-
if (path.length < 2) {
|
|
3380
|
-
continue;
|
|
3381
|
-
}
|
|
3382
|
-
switch (path[0]) {
|
|
3383
|
-
case "objects":
|
|
3384
|
-
if (path.length >= 2) {
|
|
3385
|
-
inlineChangedObjectIds.add(path[1]);
|
|
3386
|
-
}
|
|
3387
|
-
break;
|
|
3388
|
-
}
|
|
3389
|
-
}
|
|
3390
|
-
return [
|
|
3391
|
-
...inlineChangedObjectIds
|
|
3392
|
-
];
|
|
3393
|
-
};
|
|
3394
|
-
var getSpaceKeyFromDoc = (doc) => {
|
|
3395
|
-
const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
|
|
3396
|
-
if (rawSpaceKey == null) {
|
|
3397
|
-
return null;
|
|
3398
|
-
}
|
|
3399
|
-
return String(rawSpaceKey);
|
|
3400
|
-
};
|
|
3401
|
-
|
|
3402
2772
|
export {
|
|
3403
2773
|
codec,
|
|
3404
2774
|
valueEncoding,
|
|
@@ -3423,11 +2793,6 @@ export {
|
|
|
3423
2793
|
SpaceProtocol,
|
|
3424
2794
|
AuthStatus,
|
|
3425
2795
|
SpaceProtocolSession,
|
|
3426
|
-
SpaceManager
|
|
3427
|
-
AutomergeStorageAdapter,
|
|
3428
|
-
LocalHostNetworkAdapter,
|
|
3429
|
-
MeshNetworkAdapter,
|
|
3430
|
-
AutomergeHost,
|
|
3431
|
-
getSpaceKeyFromDoc
|
|
2796
|
+
SpaceManager
|
|
3432
2797
|
};
|
|
3433
|
-
//# sourceMappingURL=chunk-
|
|
2798
|
+
//# sourceMappingURL=chunk-WAN2XUWE.mjs.map
|