@muhkoo/connect 0.10.2-alpha.0 → 0.10.4-alpha.0
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/browser/index.js +45 -5
- package/dist/browser/index.js.map +1 -1
- package/dist/connect.d.ts +7 -0
- package/dist/server/index.js +45 -5
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.js
CHANGED
|
@@ -5057,7 +5057,7 @@ function base64UrlDecode(s) {
|
|
|
5057
5057
|
* expect (and isn't serving a stale cached bundle). Keep this in sync with
|
|
5058
5058
|
* `package.json` `version`.
|
|
5059
5059
|
*/
|
|
5060
|
-
const VERSION = "0.10.
|
|
5060
|
+
const VERSION = "0.10.4-alpha.0";
|
|
5061
5061
|
|
|
5062
5062
|
/**
|
|
5063
5063
|
* `HttpClient` — the one place the unified {@link Client} talks to the
|
|
@@ -8812,14 +8812,20 @@ class WebRtcTransport {
|
|
|
8812
8812
|
offSignal;
|
|
8813
8813
|
iceServers;
|
|
8814
8814
|
maxPeers;
|
|
8815
|
+
debug;
|
|
8815
8816
|
nextMsgId = 1;
|
|
8816
8817
|
constructor(signaler, myId, opts = {}) {
|
|
8817
8818
|
this.signaler = signaler;
|
|
8818
8819
|
this.myId = myId;
|
|
8819
8820
|
this.iceServers = opts.iceServers ?? DEFAULT_ICE;
|
|
8820
8821
|
this.maxPeers = opts.maxPeers ?? 8;
|
|
8822
|
+
this.debug = opts.debug ?? false;
|
|
8821
8823
|
this.offSignal = this.signaler.onSignal((from, kind, data) => this.onSignal(from, kind, data));
|
|
8822
8824
|
}
|
|
8825
|
+
log(...a) {
|
|
8826
|
+
if (this.debug)
|
|
8827
|
+
console.info("[muhkoo:p2p]", ...a);
|
|
8828
|
+
}
|
|
8823
8829
|
peers() {
|
|
8824
8830
|
return [...this.conns].filter(([, c]) => c.dc?.readyState === "open").map(([id]) => id);
|
|
8825
8831
|
}
|
|
@@ -8870,19 +8876,42 @@ class WebRtcTransport {
|
|
|
8870
8876
|
// -- internals -----------------------------------------------------------
|
|
8871
8877
|
newPc(peerId) {
|
|
8872
8878
|
const pc = new RTCPeerConnection({ iceServers: this.iceServers });
|
|
8873
|
-
const conn = { pc, reasm: new Map() };
|
|
8879
|
+
const conn = { pc, reasm: new Map(), remoteSet: false, pendingIce: [] };
|
|
8874
8880
|
this.conns.set(peerId, conn);
|
|
8881
|
+
const short = String(peerId).slice(0, 8);
|
|
8875
8882
|
pc.onicecandidate = (e) => {
|
|
8876
|
-
if (e.candidate)
|
|
8883
|
+
if (e.candidate) {
|
|
8884
|
+
this.log(`${short} local candidate ${e.candidate.type ?? "?"} ${(e.candidate.address ?? e.candidate.candidate).toString().slice(0, 40)}`);
|
|
8877
8885
|
this.signaler.send(peerId, "ice", e.candidate.toJSON());
|
|
8886
|
+
}
|
|
8878
8887
|
};
|
|
8879
8888
|
pc.onconnectionstatechange = () => {
|
|
8889
|
+
this.log(`${short} connection=${pc.connectionState}`);
|
|
8880
8890
|
if (["failed", "closed", "disconnected"].includes(pc.connectionState))
|
|
8881
8891
|
this.drop(peerId);
|
|
8882
8892
|
};
|
|
8893
|
+
if (this.debug) {
|
|
8894
|
+
pc.oniceconnectionstatechange = () => this.log(`${short} ice=${pc.iceConnectionState}`);
|
|
8895
|
+
pc.onicegatheringstatechange = () => this.log(`${short} gathering=${pc.iceGatheringState}`);
|
|
8896
|
+
}
|
|
8883
8897
|
pc.ondatachannel = (e) => this.bindChannel(peerId, conn, e.channel);
|
|
8884
8898
|
return conn;
|
|
8885
8899
|
}
|
|
8900
|
+
/** Mark a peer's remote description as set and apply any ICE candidates that
|
|
8901
|
+
* arrived before it (dropping them, the old behavior, breaks LAN dials). */
|
|
8902
|
+
async markRemoteSet(conn) {
|
|
8903
|
+
conn.remoteSet = true;
|
|
8904
|
+
const pending = conn.pendingIce;
|
|
8905
|
+
conn.pendingIce = [];
|
|
8906
|
+
for (const cand of pending) {
|
|
8907
|
+
try {
|
|
8908
|
+
await conn.pc.addIceCandidate(cand);
|
|
8909
|
+
}
|
|
8910
|
+
catch { /* stale/duplicate */ }
|
|
8911
|
+
}
|
|
8912
|
+
if (pending.length)
|
|
8913
|
+
this.log(`flushed ${pending.length} queued ICE candidate(s)`);
|
|
8914
|
+
}
|
|
8886
8915
|
async initiate(peerId) {
|
|
8887
8916
|
const conn = this.newPc(peerId);
|
|
8888
8917
|
const dc = conn.pc.createDataChannel("blocks");
|
|
@@ -8904,22 +8933,32 @@ class WebRtcTransport {
|
|
|
8904
8933
|
return; // mesh cap
|
|
8905
8934
|
const conn = this.conns.get(from) ?? this.newPc(from);
|
|
8906
8935
|
await conn.pc.setRemoteDescription(data);
|
|
8936
|
+
await this.markRemoteSet(conn);
|
|
8907
8937
|
const answer = await conn.pc.createAnswer();
|
|
8908
8938
|
await conn.pc.setLocalDescription(answer);
|
|
8909
8939
|
this.signaler.send(from, "answer", answer);
|
|
8910
8940
|
}
|
|
8911
8941
|
else if (kind === "answer") {
|
|
8912
8942
|
const conn = this.conns.get(from);
|
|
8913
|
-
if (conn)
|
|
8943
|
+
if (conn) {
|
|
8914
8944
|
await conn.pc.setRemoteDescription(data);
|
|
8945
|
+
await this.markRemoteSet(conn);
|
|
8946
|
+
}
|
|
8915
8947
|
}
|
|
8916
8948
|
else if (kind === "ice") {
|
|
8917
8949
|
const conn = this.conns.get(from);
|
|
8918
8950
|
if (conn && data) {
|
|
8951
|
+
// Queue candidates that arrive before setRemoteDescription — adding
|
|
8952
|
+
// them early throws and (previously) dropped them, which killed the
|
|
8953
|
+
// connection on fast LANs where ICE beats the SDP answer.
|
|
8954
|
+
if (!conn.remoteSet) {
|
|
8955
|
+
conn.pendingIce.push(data);
|
|
8956
|
+
return;
|
|
8957
|
+
}
|
|
8919
8958
|
try {
|
|
8920
8959
|
await conn.pc.addIceCandidate(data);
|
|
8921
8960
|
}
|
|
8922
|
-
catch { /*
|
|
8961
|
+
catch { /* stale */ }
|
|
8923
8962
|
}
|
|
8924
8963
|
}
|
|
8925
8964
|
else if (kind === "bye") {
|
|
@@ -9388,6 +9427,7 @@ class PeerNetwork {
|
|
|
9388
9427
|
new WebRtcTransport(this.signaler, opts.myId, {
|
|
9389
9428
|
iceServers: opts.iceServers,
|
|
9390
9429
|
maxPeers: opts.maxPeers,
|
|
9430
|
+
debug: opts.debug,
|
|
9391
9431
|
});
|
|
9392
9432
|
this.host = buildEngineHost(opts);
|
|
9393
9433
|
// Wire transport ⇄ engine, demuxing block (engine) from gossip (app).
|