@leofcoin/chain 1.7.103 → 1.7.104
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/exports/browser/chain.js +26 -163
- package/exports/chain.js +26 -163
- package/package.json +1 -1
package/exports/browser/chain.js
CHANGED
|
@@ -5347,13 +5347,13 @@ class ConnectionMonitor {
|
|
|
5347
5347
|
void this.#restoreNetwork();
|
|
5348
5348
|
};
|
|
5349
5349
|
window.addEventListener('online', this.#onOnline);
|
|
5350
|
-
this.#onVisibilityChange = () => {
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
}
|
|
5356
|
-
document.addEventListener('visibilitychange', this.#onVisibilityChange)
|
|
5350
|
+
// this.#onVisibilityChange = () => {
|
|
5351
|
+
// if (document.visibilityState === 'visible') {
|
|
5352
|
+
// console.log('💡 Visibility regained — attempting restore')
|
|
5353
|
+
// void this.#restoreNetwork()
|
|
5354
|
+
// }
|
|
5355
|
+
// }
|
|
5356
|
+
// document.addEventListener('visibilitychange', this.#onVisibilityChange)
|
|
5357
5357
|
}
|
|
5358
5358
|
if (typeof process !== 'undefined' && typeof process.on === 'function') {
|
|
5359
5359
|
this.#onSigcont = () => {
|
|
@@ -5415,18 +5415,18 @@ class ConnectionMonitor {
|
|
|
5415
5415
|
// Could attempt to find compatible peers or trigger version negotiation
|
|
5416
5416
|
}
|
|
5417
5417
|
// Log disconnected peers
|
|
5418
|
-
const disconnectedPeers = this.disconnectedPeers
|
|
5419
|
-
if (disconnectedPeers.length > 0) {
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
}
|
|
5418
|
+
// const disconnectedPeers = this.disconnectedPeers
|
|
5419
|
+
// if (disconnectedPeers.length > 0) {
|
|
5420
|
+
// console.warn(`⚠️ Disconnected peers: ${disconnectedPeers.map((peer) => peer.peerId).join(', ')}`)
|
|
5421
|
+
// // Attempt to reconnect each disconnected peer sequentially to avoid racing signaling/state
|
|
5422
|
+
// for (const peer of disconnectedPeers) {
|
|
5423
|
+
// // small spacing between attempts to reduce signaling races
|
|
5424
|
+
// // eslint-disable-next-line no-await-in-loop
|
|
5425
|
+
// await new Promise((r) => setTimeout(r, 150))
|
|
5426
|
+
// // eslint-disable-next-line no-await-in-loop
|
|
5427
|
+
// await this.#attemptPeerReconnection(peer)
|
|
5428
|
+
// }
|
|
5429
|
+
// }
|
|
5430
5430
|
// Publish connection status
|
|
5431
5431
|
globalThis.pubsub?.publish('connection-status', {
|
|
5432
5432
|
connected: connectedPeers.length,
|
|
@@ -5434,71 +5434,6 @@ class ConnectionMonitor {
|
|
|
5434
5434
|
healthy: compatiblePeers.length > 0
|
|
5435
5435
|
});
|
|
5436
5436
|
}
|
|
5437
|
-
async #attemptPeerReconnection(peer) {
|
|
5438
|
-
if (!peer)
|
|
5439
|
-
return;
|
|
5440
|
-
const peerId = peer.peerId || peer.id;
|
|
5441
|
-
if (!peerId)
|
|
5442
|
-
return;
|
|
5443
|
-
if (!this.#peerReconnectAttempts[peerId]) {
|
|
5444
|
-
this.#peerReconnectAttempts[peerId] = 0;
|
|
5445
|
-
}
|
|
5446
|
-
if (this.#peerReconnectAttempts[peerId] >= this.#maxReconnectAttempts) {
|
|
5447
|
-
console.error('❌ Max reconnection attempts reached for', peerId);
|
|
5448
|
-
this.#peerReconnectAttempts[peerId] = 0;
|
|
5449
|
-
return;
|
|
5450
|
-
}
|
|
5451
|
-
this.#peerReconnectAttempts[peerId]++;
|
|
5452
|
-
console.log(`🔄 Attempting reconnection ${this.#peerReconnectAttempts[peerId]}/${this.#maxReconnectAttempts} for ${peerId}`);
|
|
5453
|
-
try {
|
|
5454
|
-
const peernet = globalThis.peernet;
|
|
5455
|
-
if (!peernet) {
|
|
5456
|
-
console.warn('⚠️ globalThis.peernet not available');
|
|
5457
|
-
return;
|
|
5458
|
-
}
|
|
5459
|
-
// Try targeted reconnect if available
|
|
5460
|
-
if (peernet.client?.reconnect) {
|
|
5461
|
-
try {
|
|
5462
|
-
await peernet.client.reconnect(peerId, peernet.stars?.[0]);
|
|
5463
|
-
return;
|
|
5464
|
-
}
|
|
5465
|
-
catch (err) {
|
|
5466
|
-
const msg = String(err?.message || err);
|
|
5467
|
-
console.warn('⚠️ Targeted reconnect failed:', msg);
|
|
5468
|
-
// handle signaling/state mismatches by cleaning up only that peer and retrying targeted reconnect
|
|
5469
|
-
if (msg.includes('Called in wrong state') ||
|
|
5470
|
-
msg.includes('setRemoteDescription') ||
|
|
5471
|
-
msg.includes('channelNames') ||
|
|
5472
|
-
msg.includes("channelNames don't match")) {
|
|
5473
|
-
console.warn('⚠️ Detected signaling/channel mismatch — cleaning up peer state and retrying targeted reconnect');
|
|
5474
|
-
try {
|
|
5475
|
-
await this.#cleanupPeerState(peerId, peernet);
|
|
5476
|
-
// small backoff before retry
|
|
5477
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
5478
|
-
await peernet.client.reconnect(peerId, peernet.stars?.[0]);
|
|
5479
|
-
return;
|
|
5480
|
-
}
|
|
5481
|
-
catch (retryErr) {
|
|
5482
|
-
console.warn('⚠️ Retry targeted reconnect failed:', String(retryErr?.message || retryErr));
|
|
5483
|
-
// fall through to non-targeted fallback below
|
|
5484
|
-
}
|
|
5485
|
-
}
|
|
5486
|
-
throw err;
|
|
5487
|
-
}
|
|
5488
|
-
}
|
|
5489
|
-
// If no targeted reconnect, try start/restore
|
|
5490
|
-
if (peernet.start) {
|
|
5491
|
-
await peernet.start();
|
|
5492
|
-
}
|
|
5493
|
-
}
|
|
5494
|
-
catch (error) {
|
|
5495
|
-
console.error('❌ Reconnection failed:', error?.message || error);
|
|
5496
|
-
// As fallback, try full restart only if even the cleanup+retry failed
|
|
5497
|
-
if (globalThis.peernet) {
|
|
5498
|
-
await this.#performFullRestart(globalThis.peernet);
|
|
5499
|
-
}
|
|
5500
|
-
}
|
|
5501
|
-
}
|
|
5502
5437
|
// helper: try to close/destroy a single peer connection and remove it from peernet's map
|
|
5503
5438
|
async #cleanupPeerState(peerId, peernet) {
|
|
5504
5439
|
try {
|
|
@@ -5541,64 +5476,17 @@ class ConnectionMonitor {
|
|
|
5541
5476
|
// ignore cleanup errors
|
|
5542
5477
|
}
|
|
5543
5478
|
}
|
|
5544
|
-
// New helper: close stale RTCPeerConnections if present and then restart peernet
|
|
5545
|
-
async #performFullRestart(peernet) {
|
|
5546
|
-
try {
|
|
5547
|
-
// Close underlying peer RTCPeerConnections if the library exposes them
|
|
5548
|
-
try {
|
|
5549
|
-
const conns = peernet.connections || {};
|
|
5550
|
-
for (const id of Object.keys(conns)) {
|
|
5551
|
-
const p = conns[id];
|
|
5552
|
-
// try to close underlying RTCPeerConnection if exposed
|
|
5553
|
-
if (p && p.pc && typeof p.pc.close === 'function') {
|
|
5554
|
-
try {
|
|
5555
|
-
p.pc.close();
|
|
5556
|
-
}
|
|
5557
|
-
catch (e) {
|
|
5558
|
-
// ignore
|
|
5559
|
-
}
|
|
5560
|
-
}
|
|
5561
|
-
}
|
|
5562
|
-
}
|
|
5563
|
-
catch (e) {
|
|
5564
|
-
// ignore
|
|
5565
|
-
}
|
|
5566
|
-
// If the library supports stop -> start, do that to fully reset signaling state
|
|
5567
|
-
if (typeof peernet.stop === 'function') {
|
|
5568
|
-
try {
|
|
5569
|
-
await peernet.stop();
|
|
5570
|
-
}
|
|
5571
|
-
catch (e) {
|
|
5572
|
-
// ignore stop errors
|
|
5573
|
-
}
|
|
5574
|
-
}
|
|
5575
|
-
// small delay to ensure sockets/RTCs are closed
|
|
5576
|
-
await new Promise((r) => setTimeout(r, 250));
|
|
5577
|
-
if (typeof peernet.start === 'function') {
|
|
5578
|
-
await peernet.start();
|
|
5579
|
-
}
|
|
5580
|
-
else {
|
|
5581
|
-
console.warn('⚠️ peernet.start not available for full restart');
|
|
5582
|
-
}
|
|
5583
|
-
// reset reconnect attempts so we can try fresh
|
|
5584
|
-
this.#peerReconnectAttempts = {};
|
|
5585
|
-
console.log('✅ Full peernet restart completed');
|
|
5586
|
-
}
|
|
5587
|
-
catch (e) {
|
|
5588
|
-
console.error('❌ Full restart failed:', e?.message || e);
|
|
5589
|
-
}
|
|
5590
|
-
}
|
|
5591
5479
|
// Called on visibility/online/resume events
|
|
5592
5480
|
async #restoreNetwork() {
|
|
5593
5481
|
console.log('🔁 Restoring network after resume/wake');
|
|
5482
|
+
globalThis.peernet.client.reinit();
|
|
5594
5483
|
// If there is a peernet instance, try a safe restore
|
|
5595
|
-
if (globalThis.peernet) {
|
|
5596
|
-
|
|
5597
|
-
}
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
}
|
|
5484
|
+
// if (globalThis.peernet) {
|
|
5485
|
+
// await this.#performFullRestart(globalThis.peernet)
|
|
5486
|
+
// } else {
|
|
5487
|
+
// // If no global peernet, attempt a normal reconnection flow
|
|
5488
|
+
// await this.#attemptReconnection()
|
|
5489
|
+
// }
|
|
5602
5490
|
}
|
|
5603
5491
|
async waitForPeers(timeoutMs = 30000) {
|
|
5604
5492
|
return new Promise((resolve) => {
|
|
@@ -5620,31 +5508,6 @@ class ConnectionMonitor {
|
|
|
5620
5508
|
// New: attempt reconnection flow (gentle start + sequential per-peer reconnect)
|
|
5621
5509
|
async #attemptReconnection() {
|
|
5622
5510
|
console.warn('⚠️ Attempting to reconnect to peers...');
|
|
5623
|
-
try {
|
|
5624
|
-
// attempt targeted reconnection for disconnected peers sequentially (avoid racing WebRTC state)
|
|
5625
|
-
const disconnected = this.disconnectedPeers;
|
|
5626
|
-
for (const p of disconnected) {
|
|
5627
|
-
// small spacing between attempts to reduce signaling races
|
|
5628
|
-
// eslint-disable-next-line no-await-in-loop
|
|
5629
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
5630
|
-
// eslint-disable-next-line no-await-in-loop
|
|
5631
|
-
await this.#attemptPeerReconnection(p);
|
|
5632
|
-
}
|
|
5633
|
-
// pause before next health check cycle
|
|
5634
|
-
await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
|
|
5635
|
-
}
|
|
5636
|
-
catch (error) {
|
|
5637
|
-
console.error('❌ Reconnection failed:', error?.message || error);
|
|
5638
|
-
if (this.#reconnectDelay >= 30000) {
|
|
5639
|
-
console.warn('⚠️ Reconnection delay reached maximum, resetting to 5 seconds');
|
|
5640
|
-
this.#reconnectDelay = 5000;
|
|
5641
|
-
}
|
|
5642
|
-
else {
|
|
5643
|
-
// exponential-ish backoff
|
|
5644
|
-
this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
|
|
5645
|
-
console.warn(`⚠️ Increasing reconnection delay to ${this.#reconnectDelay} ms`);
|
|
5646
|
-
}
|
|
5647
|
-
}
|
|
5648
5511
|
}
|
|
5649
5512
|
}
|
|
5650
5513
|
|
package/exports/chain.js
CHANGED
|
@@ -1493,13 +1493,13 @@ class ConnectionMonitor {
|
|
|
1493
1493
|
void this.#restoreNetwork();
|
|
1494
1494
|
};
|
|
1495
1495
|
window.addEventListener('online', this.#onOnline);
|
|
1496
|
-
this.#onVisibilityChange = () => {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
document.addEventListener('visibilitychange', this.#onVisibilityChange)
|
|
1496
|
+
// this.#onVisibilityChange = () => {
|
|
1497
|
+
// if (document.visibilityState === 'visible') {
|
|
1498
|
+
// console.log('💡 Visibility regained — attempting restore')
|
|
1499
|
+
// void this.#restoreNetwork()
|
|
1500
|
+
// }
|
|
1501
|
+
// }
|
|
1502
|
+
// document.addEventListener('visibilitychange', this.#onVisibilityChange)
|
|
1503
1503
|
}
|
|
1504
1504
|
if (typeof process !== 'undefined' && typeof process.on === 'function') {
|
|
1505
1505
|
this.#onSigcont = () => {
|
|
@@ -1561,18 +1561,18 @@ class ConnectionMonitor {
|
|
|
1561
1561
|
// Could attempt to find compatible peers or trigger version negotiation
|
|
1562
1562
|
}
|
|
1563
1563
|
// Log disconnected peers
|
|
1564
|
-
const disconnectedPeers = this.disconnectedPeers
|
|
1565
|
-
if (disconnectedPeers.length > 0) {
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
}
|
|
1564
|
+
// const disconnectedPeers = this.disconnectedPeers
|
|
1565
|
+
// if (disconnectedPeers.length > 0) {
|
|
1566
|
+
// console.warn(`⚠️ Disconnected peers: ${disconnectedPeers.map((peer) => peer.peerId).join(', ')}`)
|
|
1567
|
+
// // Attempt to reconnect each disconnected peer sequentially to avoid racing signaling/state
|
|
1568
|
+
// for (const peer of disconnectedPeers) {
|
|
1569
|
+
// // small spacing between attempts to reduce signaling races
|
|
1570
|
+
// // eslint-disable-next-line no-await-in-loop
|
|
1571
|
+
// await new Promise((r) => setTimeout(r, 150))
|
|
1572
|
+
// // eslint-disable-next-line no-await-in-loop
|
|
1573
|
+
// await this.#attemptPeerReconnection(peer)
|
|
1574
|
+
// }
|
|
1575
|
+
// }
|
|
1576
1576
|
// Publish connection status
|
|
1577
1577
|
globalThis.pubsub?.publish('connection-status', {
|
|
1578
1578
|
connected: connectedPeers.length,
|
|
@@ -1580,71 +1580,6 @@ class ConnectionMonitor {
|
|
|
1580
1580
|
healthy: compatiblePeers.length > 0
|
|
1581
1581
|
});
|
|
1582
1582
|
}
|
|
1583
|
-
async #attemptPeerReconnection(peer) {
|
|
1584
|
-
if (!peer)
|
|
1585
|
-
return;
|
|
1586
|
-
const peerId = peer.peerId || peer.id;
|
|
1587
|
-
if (!peerId)
|
|
1588
|
-
return;
|
|
1589
|
-
if (!this.#peerReconnectAttempts[peerId]) {
|
|
1590
|
-
this.#peerReconnectAttempts[peerId] = 0;
|
|
1591
|
-
}
|
|
1592
|
-
if (this.#peerReconnectAttempts[peerId] >= this.#maxReconnectAttempts) {
|
|
1593
|
-
console.error('❌ Max reconnection attempts reached for', peerId);
|
|
1594
|
-
this.#peerReconnectAttempts[peerId] = 0;
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
this.#peerReconnectAttempts[peerId]++;
|
|
1598
|
-
console.log(`🔄 Attempting reconnection ${this.#peerReconnectAttempts[peerId]}/${this.#maxReconnectAttempts} for ${peerId}`);
|
|
1599
|
-
try {
|
|
1600
|
-
const peernet = globalThis.peernet;
|
|
1601
|
-
if (!peernet) {
|
|
1602
|
-
console.warn('⚠️ globalThis.peernet not available');
|
|
1603
|
-
return;
|
|
1604
|
-
}
|
|
1605
|
-
// Try targeted reconnect if available
|
|
1606
|
-
if (peernet.client?.reconnect) {
|
|
1607
|
-
try {
|
|
1608
|
-
await peernet.client.reconnect(peerId, peernet.stars?.[0]);
|
|
1609
|
-
return;
|
|
1610
|
-
}
|
|
1611
|
-
catch (err) {
|
|
1612
|
-
const msg = String(err?.message || err);
|
|
1613
|
-
console.warn('⚠️ Targeted reconnect failed:', msg);
|
|
1614
|
-
// handle signaling/state mismatches by cleaning up only that peer and retrying targeted reconnect
|
|
1615
|
-
if (msg.includes('Called in wrong state') ||
|
|
1616
|
-
msg.includes('setRemoteDescription') ||
|
|
1617
|
-
msg.includes('channelNames') ||
|
|
1618
|
-
msg.includes("channelNames don't match")) {
|
|
1619
|
-
console.warn('⚠️ Detected signaling/channel mismatch — cleaning up peer state and retrying targeted reconnect');
|
|
1620
|
-
try {
|
|
1621
|
-
await this.#cleanupPeerState(peerId, peernet);
|
|
1622
|
-
// small backoff before retry
|
|
1623
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
1624
|
-
await peernet.client.reconnect(peerId, peernet.stars?.[0]);
|
|
1625
|
-
return;
|
|
1626
|
-
}
|
|
1627
|
-
catch (retryErr) {
|
|
1628
|
-
console.warn('⚠️ Retry targeted reconnect failed:', String(retryErr?.message || retryErr));
|
|
1629
|
-
// fall through to non-targeted fallback below
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
throw err;
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
// If no targeted reconnect, try start/restore
|
|
1636
|
-
if (peernet.start) {
|
|
1637
|
-
await peernet.start();
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
catch (error) {
|
|
1641
|
-
console.error('❌ Reconnection failed:', error?.message || error);
|
|
1642
|
-
// As fallback, try full restart only if even the cleanup+retry failed
|
|
1643
|
-
if (globalThis.peernet) {
|
|
1644
|
-
await this.#performFullRestart(globalThis.peernet);
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
1583
|
// helper: try to close/destroy a single peer connection and remove it from peernet's map
|
|
1649
1584
|
async #cleanupPeerState(peerId, peernet) {
|
|
1650
1585
|
try {
|
|
@@ -1687,64 +1622,17 @@ class ConnectionMonitor {
|
|
|
1687
1622
|
// ignore cleanup errors
|
|
1688
1623
|
}
|
|
1689
1624
|
}
|
|
1690
|
-
// New helper: close stale RTCPeerConnections if present and then restart peernet
|
|
1691
|
-
async #performFullRestart(peernet) {
|
|
1692
|
-
try {
|
|
1693
|
-
// Close underlying peer RTCPeerConnections if the library exposes them
|
|
1694
|
-
try {
|
|
1695
|
-
const conns = peernet.connections || {};
|
|
1696
|
-
for (const id of Object.keys(conns)) {
|
|
1697
|
-
const p = conns[id];
|
|
1698
|
-
// try to close underlying RTCPeerConnection if exposed
|
|
1699
|
-
if (p && p.pc && typeof p.pc.close === 'function') {
|
|
1700
|
-
try {
|
|
1701
|
-
p.pc.close();
|
|
1702
|
-
}
|
|
1703
|
-
catch (e) {
|
|
1704
|
-
// ignore
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
catch (e) {
|
|
1710
|
-
// ignore
|
|
1711
|
-
}
|
|
1712
|
-
// If the library supports stop -> start, do that to fully reset signaling state
|
|
1713
|
-
if (typeof peernet.stop === 'function') {
|
|
1714
|
-
try {
|
|
1715
|
-
await peernet.stop();
|
|
1716
|
-
}
|
|
1717
|
-
catch (e) {
|
|
1718
|
-
// ignore stop errors
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
// small delay to ensure sockets/RTCs are closed
|
|
1722
|
-
await new Promise((r) => setTimeout(r, 250));
|
|
1723
|
-
if (typeof peernet.start === 'function') {
|
|
1724
|
-
await peernet.start();
|
|
1725
|
-
}
|
|
1726
|
-
else {
|
|
1727
|
-
console.warn('⚠️ peernet.start not available for full restart');
|
|
1728
|
-
}
|
|
1729
|
-
// reset reconnect attempts so we can try fresh
|
|
1730
|
-
this.#peerReconnectAttempts = {};
|
|
1731
|
-
console.log('✅ Full peernet restart completed');
|
|
1732
|
-
}
|
|
1733
|
-
catch (e) {
|
|
1734
|
-
console.error('❌ Full restart failed:', e?.message || e);
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
1625
|
// Called on visibility/online/resume events
|
|
1738
1626
|
async #restoreNetwork() {
|
|
1739
1627
|
console.log('🔁 Restoring network after resume/wake');
|
|
1628
|
+
globalThis.peernet.client.reinit();
|
|
1740
1629
|
// If there is a peernet instance, try a safe restore
|
|
1741
|
-
if (globalThis.peernet) {
|
|
1742
|
-
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
}
|
|
1630
|
+
// if (globalThis.peernet) {
|
|
1631
|
+
// await this.#performFullRestart(globalThis.peernet)
|
|
1632
|
+
// } else {
|
|
1633
|
+
// // If no global peernet, attempt a normal reconnection flow
|
|
1634
|
+
// await this.#attemptReconnection()
|
|
1635
|
+
// }
|
|
1748
1636
|
}
|
|
1749
1637
|
async waitForPeers(timeoutMs = 30000) {
|
|
1750
1638
|
return new Promise((resolve) => {
|
|
@@ -1766,31 +1654,6 @@ class ConnectionMonitor {
|
|
|
1766
1654
|
// New: attempt reconnection flow (gentle start + sequential per-peer reconnect)
|
|
1767
1655
|
async #attemptReconnection() {
|
|
1768
1656
|
console.warn('⚠️ Attempting to reconnect to peers...');
|
|
1769
|
-
try {
|
|
1770
|
-
// attempt targeted reconnection for disconnected peers sequentially (avoid racing WebRTC state)
|
|
1771
|
-
const disconnected = this.disconnectedPeers;
|
|
1772
|
-
for (const p of disconnected) {
|
|
1773
|
-
// small spacing between attempts to reduce signaling races
|
|
1774
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1775
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
1776
|
-
// eslint-disable-next-line no-await-in-loop
|
|
1777
|
-
await this.#attemptPeerReconnection(p);
|
|
1778
|
-
}
|
|
1779
|
-
// pause before next health check cycle
|
|
1780
|
-
await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
|
|
1781
|
-
}
|
|
1782
|
-
catch (error) {
|
|
1783
|
-
console.error('❌ Reconnection failed:', error?.message || error);
|
|
1784
|
-
if (this.#reconnectDelay >= 30000) {
|
|
1785
|
-
console.warn('⚠️ Reconnection delay reached maximum, resetting to 5 seconds');
|
|
1786
|
-
this.#reconnectDelay = 5000;
|
|
1787
|
-
}
|
|
1788
|
-
else {
|
|
1789
|
-
// exponential-ish backoff
|
|
1790
|
-
this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
|
|
1791
|
-
console.warn(`⚠️ Increasing reconnection delay to ${this.#reconnectDelay} ms`);
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
1657
|
}
|
|
1795
1658
|
}
|
|
1796
1659
|
|