@decentnetwork/lan 0.1.221 → 0.1.223
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/ui/desktop/app.js +28 -9
- package/package.json +1 -1
package/dist/ui/desktop/app.js
CHANGED
|
@@ -1848,8 +1848,8 @@ function ProfileTab({ T, me, onEdit }) {
|
|
|
1848
1848
|
}
|
|
1849
1849
|
Object.assign(window, { ProfileTab });
|
|
1850
1850
|
const DK_FILE_RTC_KIND = "file";
|
|
1851
|
-
const DK_FILE_RTC_CHUNK =
|
|
1852
|
-
const DK_FILE_RTC_OPEN_TIMEOUT_MS =
|
|
1851
|
+
const DK_FILE_RTC_CHUNK = 16 * 1024;
|
|
1852
|
+
const DK_FILE_RTC_OPEN_TIMEOUT_MS = 2e4;
|
|
1853
1853
|
const DK_FILE_RTC_SIGNAL_TTL_MS = 10 * 60 * 1e3;
|
|
1854
1854
|
function dkFileRtcId() {
|
|
1855
1855
|
if (window.crypto && window.crypto.randomUUID) return window.crypto.randomUUID();
|
|
@@ -1858,12 +1858,17 @@ function dkFileRtcId() {
|
|
|
1858
1858
|
function dkFileRtcEnvelope(fileId, type, extra) {
|
|
1859
1859
|
return Object.assign({ dkRtc: 1, kind: DK_FILE_RTC_KIND, fileId, type, ts: Date.now() }, extra || {});
|
|
1860
1860
|
}
|
|
1861
|
-
function
|
|
1861
|
+
function dkRtcState(pc) {
|
|
1862
|
+
if (!pc) return "";
|
|
1863
|
+
return "ice=" + pc.iceConnectionState + " conn=" + pc.connectionState + " gather=" + pc.iceGatheringState;
|
|
1864
|
+
}
|
|
1865
|
+
function dkWaitForOpen(dc, timeoutMs, describeState) {
|
|
1862
1866
|
if (dc.readyState === "open") return Promise.resolve();
|
|
1863
1867
|
return new Promise((resolve, reject) => {
|
|
1864
1868
|
const timer = setTimeout(() => {
|
|
1865
1869
|
cleanup();
|
|
1866
|
-
|
|
1870
|
+
const s = describeState ? describeState() : "";
|
|
1871
|
+
reject(new Error("WebRTC data channel open timed out" + (s ? " (" + s + ")" : "")));
|
|
1867
1872
|
}, timeoutMs);
|
|
1868
1873
|
const cleanup = () => {
|
|
1869
1874
|
clearTimeout(timer);
|
|
@@ -1877,11 +1882,13 @@ function dkWaitForOpen(dc, timeoutMs) {
|
|
|
1877
1882
|
};
|
|
1878
1883
|
const onError = () => {
|
|
1879
1884
|
cleanup();
|
|
1880
|
-
|
|
1885
|
+
const s = describeState ? describeState() : "";
|
|
1886
|
+
reject(new Error("WebRTC data channel failed" + (s ? " (" + s + ")" : "")));
|
|
1881
1887
|
};
|
|
1882
1888
|
const onClose = () => {
|
|
1883
1889
|
cleanup();
|
|
1884
|
-
|
|
1890
|
+
const s = describeState ? describeState() : "";
|
|
1891
|
+
reject(new Error("WebRTC data channel closed before open" + (s ? " (" + s + ")" : "")));
|
|
1885
1892
|
};
|
|
1886
1893
|
dc.addEventListener("open", onOpen);
|
|
1887
1894
|
dc.addEventListener("error", onError);
|
|
@@ -1971,8 +1978,13 @@ function useRtcFileController(selfId, onReceivedText) {
|
|
|
1971
1978
|
let sess = peersRef.current.get(fileId);
|
|
1972
1979
|
try {
|
|
1973
1980
|
if (env.type === "offer") {
|
|
1974
|
-
if (sess)
|
|
1981
|
+
if (sess && sess.pc && sess.pc.signalingState !== "closed") {
|
|
1982
|
+
console.warn("[file-rtc] duplicate offer ignored for " + fileId);
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1975
1985
|
const pc = new RTCPeerConnection({ iceServers: CALL_ICE_SERVERS });
|
|
1986
|
+
pc.oniceconnectionstatechange = () => console.warn("[file-rtc] receiver ice=" + pc.iceConnectionState + " conn=" + pc.connectionState);
|
|
1987
|
+
pc.onconnectionstatechange = () => console.warn("[file-rtc] receiver conn=" + pc.connectionState + " ice=" + pc.iceConnectionState);
|
|
1976
1988
|
pc.onicecandidate = (ev) => {
|
|
1977
1989
|
if (ev.candidate) sendSignal(peerId, fileId, "candidate", { candidate: ev.candidate.toJSON() }).catch(() => {
|
|
1978
1990
|
});
|
|
@@ -1993,6 +2005,10 @@ function useRtcFileController(selfId, onReceivedText) {
|
|
|
1993
2005
|
await pc.setLocalDescription(answer);
|
|
1994
2006
|
await sendSignal(peerId, fileId, "answer", { sdp: answer.sdp });
|
|
1995
2007
|
} else if (env.type === "answer" && sess) {
|
|
2008
|
+
if (sess.pc.signalingState !== "have-local-offer") {
|
|
2009
|
+
console.warn("[file-rtc] stale answer ignored for " + fileId + " state=" + sess.pc.signalingState);
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
1996
2012
|
await sess.pc.setRemoteDescription({ type: "answer", sdp: env.sdp });
|
|
1997
2013
|
if (sess.pendingCandidates) {
|
|
1998
2014
|
for (const c of sess.pendingCandidates.splice(0)) {
|
|
@@ -2048,6 +2064,8 @@ function useRtcFileController(selfId, onReceivedText) {
|
|
|
2048
2064
|
};
|
|
2049
2065
|
const sendSignal = (type, extra) => bus.send(peerId, dkFileRtcEnvelope(fileId, type, extra));
|
|
2050
2066
|
try {
|
|
2067
|
+
pc.oniceconnectionstatechange = () => console.warn("[file-rtc] sender ice=" + pc.iceConnectionState + " conn=" + pc.connectionState);
|
|
2068
|
+
pc.onconnectionstatechange = () => console.warn("[file-rtc] sender conn=" + pc.connectionState + " ice=" + pc.iceConnectionState);
|
|
2051
2069
|
pc.onicecandidate = (ev) => {
|
|
2052
2070
|
if (ev.candidate) sendSignal("candidate", { candidate: ev.candidate.toJSON() }).catch(() => {
|
|
2053
2071
|
});
|
|
@@ -2058,7 +2076,7 @@ function useRtcFileController(selfId, onReceivedText) {
|
|
|
2058
2076
|
sdp: offer.sdp,
|
|
2059
2077
|
meta: { name: file.name, size: file.size, mime: file.type || "application/octet-stream" }
|
|
2060
2078
|
});
|
|
2061
|
-
await dkWaitForOpen(dc, DK_FILE_RTC_OPEN_TIMEOUT_MS);
|
|
2079
|
+
await dkWaitForOpen(dc, DK_FILE_RTC_OPEN_TIMEOUT_MS, () => dkRtcState(pc));
|
|
2062
2080
|
dc.send(JSON.stringify({ type: "meta", name: file.name, size: file.size, mime: file.type || "application/octet-stream" }));
|
|
2063
2081
|
let sent = 0;
|
|
2064
2082
|
const highWater = 4 * 1024 * 1024;
|
|
@@ -2104,7 +2122,8 @@ function RtcFileInbox({ T, peers, ctl }) {
|
|
|
2104
2122
|
Object.assign(window, { useRtcFileController, RtcFileInbox });
|
|
2105
2123
|
const CALL_ICE_SERVERS = [
|
|
2106
2124
|
{ urls: "stun:stun.l.google.com:19302" },
|
|
2107
|
-
{ urls: "turn:tokyo.fi.chat:3478", username: "allcom", credential: "allcompass" }
|
|
2125
|
+
{ urls: "turn:tokyo.fi.chat:3478", username: "allcom", credential: "allcompass" },
|
|
2126
|
+
{ urls: "turn:tokyo.fi.chat:3478?transport=tcp", username: "allcom", credential: "allcompass" }
|
|
2108
2127
|
];
|
|
2109
2128
|
function useCallController(selfId) {
|
|
2110
2129
|
const [incoming, setIncoming] = React.useState(null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.223",
|
|
4
4
|
"description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|