@fairfox/polly 0.51.0 → 0.53.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/src/mesh.js +121 -7
- package/dist/src/mesh.js.map +4 -4
- package/dist/src/polly-ui/markdown.js +2 -3
- package/dist/src/polly-ui/markdown.js.map +2 -2
- package/dist/src/shared/lib/mesh-client.d.ts +29 -0
- package/dist/src/shared/lib/mesh-webrtc-adapter.d.ts +127 -6
- package/dist/tools/test/src/visual/index.js +37 -11
- package/dist/tools/test/src/visual/index.js.map +4 -4
- package/package.json +1 -1
package/dist/src/mesh.js
CHANGED
|
@@ -1943,6 +1943,9 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
1943
1943
|
iceServers;
|
|
1944
1944
|
dataChannelLabel;
|
|
1945
1945
|
knownPeers;
|
|
1946
|
+
keyringSource;
|
|
1947
|
+
knownPeersRefreshTimer;
|
|
1948
|
+
knownPeersRefreshIntervalMs;
|
|
1946
1949
|
presentPeers = new Set;
|
|
1947
1950
|
localPeerId;
|
|
1948
1951
|
RTCPeerConnectionCtor;
|
|
@@ -1950,8 +1953,17 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
1950
1953
|
ready = false;
|
|
1951
1954
|
readyResolver;
|
|
1952
1955
|
get knownPeerIds() {
|
|
1956
|
+
if (this.keyringSource !== undefined) {
|
|
1957
|
+
return [...this.keyringSource().knownPeers.keys()].filter((id) => id !== this.localPeerId);
|
|
1958
|
+
}
|
|
1953
1959
|
return [...this.knownPeers];
|
|
1954
1960
|
}
|
|
1961
|
+
hasKnownPeer(remotePeerId) {
|
|
1962
|
+
if (this.keyringSource !== undefined) {
|
|
1963
|
+
return this.keyringSource().knownPeers.has(remotePeerId);
|
|
1964
|
+
}
|
|
1965
|
+
return this.knownPeers.has(remotePeerId);
|
|
1966
|
+
}
|
|
1955
1967
|
onBlobMessage;
|
|
1956
1968
|
constructor(options) {
|
|
1957
1969
|
super();
|
|
@@ -1959,6 +1971,8 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
1959
1971
|
this.iceServers = options.iceServers ?? DEFAULT_ICE_SERVERS;
|
|
1960
1972
|
this.dataChannelLabel = options.dataChannelLabel ?? "polly-mesh";
|
|
1961
1973
|
this.knownPeers = new Set(options.knownPeerIds ?? []);
|
|
1974
|
+
this.keyringSource = options.keyringSource;
|
|
1975
|
+
this.knownPeersRefreshIntervalMs = options.knownPeersRefreshIntervalMs ?? 2000;
|
|
1962
1976
|
this.localPeerId = options.peerId;
|
|
1963
1977
|
const PC = options.RTCPeerConnection ?? globalThis.RTCPeerConnection;
|
|
1964
1978
|
if (typeof PC !== "function") {
|
|
@@ -1972,6 +1986,41 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
1972
1986
|
peerSlotCount() {
|
|
1973
1987
|
return this.slots.size;
|
|
1974
1988
|
}
|
|
1989
|
+
getPeerStateSnapshot() {
|
|
1990
|
+
const knownPeerIds = this.knownPeerIds;
|
|
1991
|
+
const presentPeerIds = [...this.presentPeers];
|
|
1992
|
+
const knownPeerSet = new Set(knownPeerIds);
|
|
1993
|
+
const allPeers = new Set;
|
|
1994
|
+
for (const id of knownPeerIds)
|
|
1995
|
+
allPeers.add(id);
|
|
1996
|
+
for (const id of presentPeerIds)
|
|
1997
|
+
allPeers.add(id);
|
|
1998
|
+
for (const id of this.slots.keys())
|
|
1999
|
+
allPeers.add(id);
|
|
2000
|
+
const peers = [];
|
|
2001
|
+
for (const peerId of allPeers) {
|
|
2002
|
+
const slot = this.slots.get(peerId);
|
|
2003
|
+
peers.push({
|
|
2004
|
+
peerId,
|
|
2005
|
+
knownInKeyring: knownPeerSet.has(peerId),
|
|
2006
|
+
presentInSignalling: this.presentPeers.has(peerId),
|
|
2007
|
+
slot: slot ? {
|
|
2008
|
+
signalingState: slot.connection.signalingState,
|
|
2009
|
+
iceConnectionState: slot.connection.iceConnectionState,
|
|
2010
|
+
connectionState: slot.connection.connectionState,
|
|
2011
|
+
dataChannelState: slot.channel?.readyState ?? "no-channel",
|
|
2012
|
+
pendingSendCount: slot.pendingSends.length,
|
|
2013
|
+
pendingRemoteIceCount: slot.pendingRemoteIce.length
|
|
2014
|
+
} : undefined
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
return {
|
|
2018
|
+
localPeerId: this.localPeerId,
|
|
2019
|
+
knownPeerIds,
|
|
2020
|
+
presentPeerIds,
|
|
2021
|
+
peers
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
1975
2024
|
handlePeerJoined(remotePeerId) {
|
|
1976
2025
|
this.presentPeers.add(remotePeerId);
|
|
1977
2026
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
@@ -1998,19 +2047,28 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
1998
2047
|
addKnownPeer(remotePeerId) {
|
|
1999
2048
|
if (remotePeerId === this.localPeerId)
|
|
2000
2049
|
return;
|
|
2001
|
-
if (this.
|
|
2002
|
-
|
|
2003
|
-
|
|
2050
|
+
if (this.keyringSource === undefined) {
|
|
2051
|
+
if (this.knownPeers.has(remotePeerId))
|
|
2052
|
+
return;
|
|
2053
|
+
this.knownPeers.add(remotePeerId);
|
|
2054
|
+
}
|
|
2004
2055
|
if (!this.presentPeers.has(remotePeerId))
|
|
2005
2056
|
return;
|
|
2006
2057
|
if (!this.shouldInitiateTo(remotePeerId))
|
|
2007
2058
|
return;
|
|
2008
2059
|
this.createInitiatingSlot(remotePeerId);
|
|
2009
2060
|
}
|
|
2061
|
+
refreshKnownPeers() {
|
|
2062
|
+
for (const remotePeerId of this.presentPeers) {
|
|
2063
|
+
if (!this.shouldInitiateTo(remotePeerId))
|
|
2064
|
+
continue;
|
|
2065
|
+
this.createInitiatingSlot(remotePeerId);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2010
2068
|
shouldInitiateTo(remotePeerId) {
|
|
2011
2069
|
if (remotePeerId === this.localPeerId)
|
|
2012
2070
|
return false;
|
|
2013
|
-
if (!this.
|
|
2071
|
+
if (!this.hasKnownPeer(remotePeerId))
|
|
2014
2072
|
return false;
|
|
2015
2073
|
if (this.slots.has(remotePeerId))
|
|
2016
2074
|
return false;
|
|
@@ -2032,8 +2090,10 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2032
2090
|
}
|
|
2033
2091
|
this.ready = true;
|
|
2034
2092
|
this.readyResolver?.();
|
|
2093
|
+
this.startKnownPeersSweep();
|
|
2035
2094
|
}
|
|
2036
2095
|
disconnect() {
|
|
2096
|
+
this.stopKnownPeersSweep();
|
|
2037
2097
|
for (const slot of this.slots.values()) {
|
|
2038
2098
|
slot.channel?.close();
|
|
2039
2099
|
slot.connection.close();
|
|
@@ -2043,6 +2103,23 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2043
2103
|
this.ready = false;
|
|
2044
2104
|
this.emit("close");
|
|
2045
2105
|
}
|
|
2106
|
+
startKnownPeersSweep() {
|
|
2107
|
+
if (this.keyringSource === undefined)
|
|
2108
|
+
return;
|
|
2109
|
+
if (this.knownPeersRefreshIntervalMs <= 0)
|
|
2110
|
+
return;
|
|
2111
|
+
if (this.knownPeersRefreshTimer !== undefined)
|
|
2112
|
+
return;
|
|
2113
|
+
this.knownPeersRefreshTimer = setInterval(() => {
|
|
2114
|
+
this.refreshKnownPeers();
|
|
2115
|
+
}, this.knownPeersRefreshIntervalMs);
|
|
2116
|
+
}
|
|
2117
|
+
stopKnownPeersSweep() {
|
|
2118
|
+
if (this.knownPeersRefreshTimer === undefined)
|
|
2119
|
+
return;
|
|
2120
|
+
clearInterval(this.knownPeersRefreshTimer);
|
|
2121
|
+
this.knownPeersRefreshTimer = undefined;
|
|
2122
|
+
}
|
|
2046
2123
|
send(message) {
|
|
2047
2124
|
const targetId = message.targetId;
|
|
2048
2125
|
const bytes = this.serialiseMessage(message);
|
|
@@ -2091,7 +2168,8 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2091
2168
|
connection,
|
|
2092
2169
|
channel,
|
|
2093
2170
|
pendingSends: [],
|
|
2094
|
-
pendingFragments: new Map
|
|
2171
|
+
pendingFragments: new Map,
|
|
2172
|
+
pendingRemoteIce: []
|
|
2095
2173
|
};
|
|
2096
2174
|
this.slots.set(targetId, slot);
|
|
2097
2175
|
this.wireConnection(targetId, connection);
|
|
@@ -2120,7 +2198,8 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2120
2198
|
connection,
|
|
2121
2199
|
channel: undefined,
|
|
2122
2200
|
pendingSends: [],
|
|
2123
|
-
pendingFragments: new Map
|
|
2201
|
+
pendingFragments: new Map,
|
|
2202
|
+
pendingRemoteIce: []
|
|
2124
2203
|
};
|
|
2125
2204
|
this.slots.set(fromPeerId, slot);
|
|
2126
2205
|
this.wireConnection(fromPeerId, connection);
|
|
@@ -2129,6 +2208,7 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2129
2208
|
this.wireDataChannel(fromPeerId, event.channel);
|
|
2130
2209
|
};
|
|
2131
2210
|
await connection.setRemoteDescription(sdp);
|
|
2211
|
+
await this.flushPendingRemoteIce(slot);
|
|
2132
2212
|
const answer = await connection.createAnswer();
|
|
2133
2213
|
await connection.setLocalDescription(answer);
|
|
2134
2214
|
this.signaling.sendSignal(fromPeerId, {
|
|
@@ -2143,15 +2223,31 @@ class MeshWebRTCAdapter extends NetworkAdapter2 {
|
|
|
2143
2223
|
if (slot.connection.signalingState !== "have-local-offer")
|
|
2144
2224
|
return;
|
|
2145
2225
|
await slot.connection.setRemoteDescription(sdp);
|
|
2226
|
+
await this.flushPendingRemoteIce(slot);
|
|
2146
2227
|
}
|
|
2147
2228
|
async handleIceCandidate(fromPeerId, candidate) {
|
|
2148
2229
|
const slot = this.slots.get(fromPeerId);
|
|
2149
2230
|
if (!slot)
|
|
2150
2231
|
return;
|
|
2232
|
+
if (slot.connection.remoteDescription === null) {
|
|
2233
|
+
slot.pendingRemoteIce.push(candidate);
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2151
2236
|
try {
|
|
2152
2237
|
await slot.connection.addIceCandidate(candidate);
|
|
2153
2238
|
} catch {}
|
|
2154
2239
|
}
|
|
2240
|
+
async flushPendingRemoteIce(slot) {
|
|
2241
|
+
if (slot.pendingRemoteIce.length === 0)
|
|
2242
|
+
return;
|
|
2243
|
+
const queued = slot.pendingRemoteIce;
|
|
2244
|
+
slot.pendingRemoteIce = [];
|
|
2245
|
+
for (const candidate of queued) {
|
|
2246
|
+
try {
|
|
2247
|
+
await slot.connection.addIceCandidate(candidate);
|
|
2248
|
+
} catch {}
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2155
2251
|
wireConnection(peerId, connection) {
|
|
2156
2252
|
connection.onicecandidate = (event) => {
|
|
2157
2253
|
if (event.candidate) {
|
|
@@ -2313,12 +2409,16 @@ async function createMeshClient(options) {
|
|
|
2313
2409
|
signaling: undefined,
|
|
2314
2410
|
peerId: options.signaling.peerId,
|
|
2315
2411
|
knownPeerIds,
|
|
2412
|
+
keyringSource,
|
|
2316
2413
|
...resolvedIceServers !== undefined && { iceServers: resolvedIceServers },
|
|
2317
2414
|
...options.rtc?.dataChannelLabel !== undefined && {
|
|
2318
2415
|
dataChannelLabel: options.rtc.dataChannelLabel
|
|
2319
2416
|
},
|
|
2320
2417
|
...options.rtc?.RTCPeerConnection !== undefined && {
|
|
2321
2418
|
RTCPeerConnection: options.rtc.RTCPeerConnection
|
|
2419
|
+
},
|
|
2420
|
+
...options.rtc?.knownPeersRefreshIntervalMs !== undefined && {
|
|
2421
|
+
knownPeersRefreshIntervalMs: options.rtc.knownPeersRefreshIntervalMs
|
|
2322
2422
|
}
|
|
2323
2423
|
};
|
|
2324
2424
|
let webrtcAdapter;
|
|
@@ -2365,6 +2465,20 @@ async function createMeshClient(options) {
|
|
|
2365
2465
|
signaling,
|
|
2366
2466
|
networkAdapter,
|
|
2367
2467
|
webrtcAdapter,
|
|
2468
|
+
refreshKnownPeers: () => {
|
|
2469
|
+
webrtcAdapter?.refreshKnownPeers();
|
|
2470
|
+
},
|
|
2471
|
+
getPeerStateSnapshot: () => {
|
|
2472
|
+
if (!webrtcAdapter) {
|
|
2473
|
+
return {
|
|
2474
|
+
localPeerId: options.signaling.peerId,
|
|
2475
|
+
knownPeerIds: [],
|
|
2476
|
+
presentPeerIds: [],
|
|
2477
|
+
peers: []
|
|
2478
|
+
};
|
|
2479
|
+
}
|
|
2480
|
+
return webrtcAdapter.getPeerStateSnapshot();
|
|
2481
|
+
},
|
|
2368
2482
|
close: async () => {
|
|
2369
2483
|
signaling.close();
|
|
2370
2484
|
webrtcAdapter?.disconnect();
|
|
@@ -2779,4 +2893,4 @@ export {
|
|
|
2779
2893
|
$meshCounter
|
|
2780
2894
|
};
|
|
2781
2895
|
|
|
2782
|
-
//# debugId=
|
|
2896
|
+
//# debugId=51457A626E5A2F2B64756E2164756E21
|