@leofcoin/chain 1.7.73 → 1.7.74

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.
@@ -5201,6 +5201,12 @@ class State extends Contract {
5201
5201
  get shouldSync() {
5202
5202
  if (this.#chainSyncing)
5203
5203
  return false;
5204
+ // Check if we have any connected peers with the same version
5205
+ const compatiblePeers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
5206
+ if (compatiblePeers.length === 0) {
5207
+ debug$1('No compatible peers available for sync');
5208
+ return false;
5209
+ }
5204
5210
  if (!this.#chainSyncing ||
5205
5211
  this.#resolveErrored ||
5206
5212
  this.#syncState === 'errored' ||
@@ -5209,6 +5215,25 @@ class State extends Contract {
5209
5215
  return true;
5210
5216
  return false;
5211
5217
  }
5218
+ async #waitForPeers(timeoutMs = 30000) {
5219
+ return new Promise((resolve) => {
5220
+ const checkPeers = () => {
5221
+ const peers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
5222
+ if (peers.length > 0) {
5223
+ resolve(true);
5224
+ }
5225
+ };
5226
+ // Check immediately
5227
+ checkPeers();
5228
+ // Set up interval to check periodically
5229
+ const interval = setInterval(checkPeers, 1000);
5230
+ // Set timeout
5231
+ setTimeout(() => {
5232
+ clearInterval(interval);
5233
+ resolve(false);
5234
+ }, timeoutMs);
5235
+ });
5236
+ }
5212
5237
  async triggerSync() {
5213
5238
  const latest = await this.#getLatestBlock();
5214
5239
  return this.syncChain(latest);
@@ -5268,6 +5293,112 @@ class VersionControl extends State {
5268
5293
  }
5269
5294
  }
5270
5295
 
5296
+ /**
5297
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
5298
+ */
5299
+ class ConnectionMonitor {
5300
+ #isMonitoring = false;
5301
+ #checkInterval = null;
5302
+ #reconnectAttempts = 0;
5303
+ #maxReconnectAttempts = 10;
5304
+ #reconnectDelay = 5000;
5305
+ #healthCheckInterval = 10000;
5306
+ get isMonitoring() {
5307
+ return this.#isMonitoring;
5308
+ }
5309
+ get connectedPeers() {
5310
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
5311
+ }
5312
+ get compatiblePeers() {
5313
+ return this.connectedPeers.filter((peer) => peer.version === this.version);
5314
+ }
5315
+ constructor(version) {
5316
+ this.version = version;
5317
+ }
5318
+ start() {
5319
+ if (this.#isMonitoring)
5320
+ return;
5321
+ this.#isMonitoring = true;
5322
+ console.log('🔄 Starting connection monitor...');
5323
+ this.#checkInterval = setInterval(() => {
5324
+ this.#healthCheck();
5325
+ }, this.#healthCheckInterval);
5326
+ // Initial health check
5327
+ this.#healthCheck();
5328
+ }
5329
+ stop() {
5330
+ if (!this.#isMonitoring)
5331
+ return;
5332
+ this.#isMonitoring = false;
5333
+ if (this.#checkInterval) {
5334
+ clearInterval(this.#checkInterval);
5335
+ this.#checkInterval = null;
5336
+ }
5337
+ console.log('⏹️ Connection monitor stopped');
5338
+ }
5339
+ async #healthCheck() {
5340
+ const connectedPeers = this.connectedPeers;
5341
+ const compatiblePeers = this.compatiblePeers;
5342
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
5343
+ if (connectedPeers.length === 0) {
5344
+ console.warn('⚠️ No peer connections detected');
5345
+ await this.#attemptReconnection();
5346
+ }
5347
+ else if (compatiblePeers.length === 0) {
5348
+ console.warn('⚠️ No compatible peers found');
5349
+ // Could attempt to find compatible peers or trigger version negotiation
5350
+ }
5351
+ else {
5352
+ // Reset reconnect attempts on successful connection
5353
+ this.#reconnectAttempts = 0;
5354
+ }
5355
+ // Publish connection status
5356
+ globalThis.pubsub?.publish('connection-status', {
5357
+ connected: connectedPeers.length,
5358
+ compatible: compatiblePeers.length,
5359
+ healthy: compatiblePeers.length > 0
5360
+ });
5361
+ }
5362
+ async #attemptReconnection() {
5363
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
5364
+ console.error('❌ Max reconnection attempts reached');
5365
+ return;
5366
+ }
5367
+ this.#reconnectAttempts++;
5368
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
5369
+ try {
5370
+ // Try to restart the network
5371
+ if (globalThis.peernet?.start) {
5372
+ await globalThis.peernet.start();
5373
+ }
5374
+ // Wait a bit before next check
5375
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
5376
+ }
5377
+ catch (error) {
5378
+ console.error('❌ Reconnection failed:', error.message);
5379
+ // Exponential backoff
5380
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
5381
+ }
5382
+ }
5383
+ async waitForPeers(timeoutMs = 30000) {
5384
+ return new Promise((resolve) => {
5385
+ const startTime = Date.now();
5386
+ const checkPeers = () => {
5387
+ if (this.compatiblePeers.length > 0) {
5388
+ resolve(true);
5389
+ return;
5390
+ }
5391
+ if (Date.now() - startTime >= timeoutMs) {
5392
+ resolve(false);
5393
+ return;
5394
+ }
5395
+ setTimeout(checkPeers, 1000);
5396
+ };
5397
+ checkPeers();
5398
+ });
5399
+ }
5400
+ }
5401
+
5271
5402
  const debug = globalThis.createDebugger('leofcoin/chain');
5272
5403
  // check if browser or local
5273
5404
  class Chain extends VersionControl {
@@ -5280,6 +5411,10 @@ class Chain extends VersionControl {
5280
5411
  #participants;
5281
5412
  #participating;
5282
5413
  #jail;
5414
+ #peerConnectionRetries;
5415
+ #maxPeerRetries;
5416
+ #peerRetryDelay;
5417
+ #connectionMonitor;
5283
5418
  constructor(config) {
5284
5419
  super(config);
5285
5420
  this.#slotTime = 10000;
@@ -5291,6 +5426,9 @@ class Chain extends VersionControl {
5291
5426
  this.#participants = [];
5292
5427
  this.#participating = false;
5293
5428
  this.#jail = [];
5429
+ this.#peerConnectionRetries = new Map();
5430
+ this.#maxPeerRetries = 5;
5431
+ this.#peerRetryDelay = 5000;
5294
5432
  this.#addTransaction = async (message) => {
5295
5433
  const transaction = new TransactionMessage(message);
5296
5434
  const hash = await transaction.hash();
@@ -5365,6 +5503,7 @@ class Chain extends VersionControl {
5365
5503
  // this.node = await new Node()
5366
5504
  this.#participants = [];
5367
5505
  this.#participating = false;
5506
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
5368
5507
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
5369
5508
  if (!initialized)
5370
5509
  await this.#setup();
@@ -5372,8 +5511,11 @@ class Chain extends VersionControl {
5372
5511
  // this.#state = new State()
5373
5512
  // todo some functions rely on state
5374
5513
  await super.init();
5514
+ // Start connection monitoring
5515
+ this.#connectionMonitor.start();
5375
5516
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
5376
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
5517
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
5518
+ return new BWMessage(bw);
5377
5519
  });
5378
5520
  // await globalThis.peernet.addRequestHandler('peerId', () => {
5379
5521
  // let node =
@@ -5454,7 +5596,7 @@ class Chain extends VersionControl {
5454
5596
  }
5455
5597
  }
5456
5598
  if (this.wantList.length > 0) {
5457
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
5599
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
5458
5600
  for (let i = 0; i < promises.length; i++) {
5459
5601
  const result = promises[i];
5460
5602
  if (result.status === 'fulfilled')
@@ -5781,7 +5923,7 @@ class Chain extends VersionControl {
5781
5923
  * @returns
5782
5924
  */
5783
5925
  internalCall(sender, contract, method, parameters) {
5784
- globalThis.msg = this.#createMessage(sender, contract);
5926
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
5785
5927
  return this.machine.execute(contract, method, parameters);
5786
5928
  }
5787
5929
  /**
@@ -5792,11 +5934,11 @@ class Chain extends VersionControl {
5792
5934
  * @returns
5793
5935
  */
5794
5936
  call(contract, method, parameters) {
5795
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5937
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5796
5938
  return this.machine.execute(contract, method, parameters);
5797
5939
  }
5798
5940
  staticCall(contract, method, parameters) {
5799
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5941
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5800
5942
  return this.machine.get(contract, method, parameters);
5801
5943
  }
5802
5944
  mint(to, amount) {
@@ -5826,6 +5968,27 @@ class Chain extends VersionControl {
5826
5968
  lookup(name) {
5827
5969
  return this.call(addresses.nameService, 'lookup', [name]);
5828
5970
  }
5971
+ #monitorPeerConnections() {
5972
+ setInterval(() => {
5973
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
5974
+ debug(`Connected peers: ${connectedPeers.length}`);
5975
+ if (connectedPeers.length === 0) {
5976
+ debug('No peers connected, attempting to reconnect...');
5977
+ this.#attemptPeerReconnection();
5978
+ }
5979
+ }, 10000); // Check every 10 seconds
5980
+ }
5981
+ async #attemptPeerReconnection() {
5982
+ try {
5983
+ // Try to reconnect to star servers
5984
+ if (globalThis.peernet && globalThis.peernet.start) {
5985
+ await globalThis.peernet.start();
5986
+ }
5987
+ }
5988
+ catch (error) {
5989
+ console.warn('Failed to reconnect to peers:', error.message);
5990
+ }
5991
+ }
5829
5992
  }
5830
5993
 
5831
5994
  export { Chain as default };
@@ -1,4 +1,4 @@
1
- import { L as LittlePubSub } from './node-browser-BvxzAdLe.js';
1
+ import { L as LittlePubSub } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { F as FormatInterface } from './node-browser-BvxzAdLe.js';
1
+ import { F as FormatInterface } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
4
4
 
@@ -8495,7 +8495,7 @@ class Peernet {
8495
8495
  this.root = options.root;
8496
8496
  const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
8497
8497
  // FolderMessageResponse
8498
- } = await import(/* webpackChunkName: "messages" */ './messages-CW17jRdc-c9cSXiiQ.js');
8498
+ } = await import(/* webpackChunkName: "messages" */ './messages-CW17jRdc-Dtrj-vba.js');
8499
8499
  /**
8500
8500
  * proto Object containing protos
8501
8501
  * @type {Object}
@@ -8589,7 +8589,7 @@ class Peernet {
8589
8589
  if (this.#starting || this.#started)
8590
8590
  return;
8591
8591
  this.#starting = true;
8592
- const importee = await import('./client-DD7vhDK_-UAymLS2i.js');
8592
+ const importee = await import('./client-DD7vhDK_-BdNAdRzV.js');
8593
8593
  /**
8594
8594
  * @access public
8595
8595
  * @type {PeernetClient}
@@ -9078,7 +9078,7 @@ globalThis.Peernet = Peernet;
9078
9078
  var networks = {
9079
9079
  leofcoin: {
9080
9080
  peach: {
9081
- stars: ['wss://star.leofcoin.org'] // todo webrtc and bittorent stars
9081
+ stars: ['wss://star-testnet.leofcoin.org', 'wss://star.leofcoin.org'] // Separate testnet stars
9082
9082
  }
9083
9083
  }
9084
9084
  };
@@ -1,3 +1,3 @@
1
- export { N as default } from './node-browser-BvxzAdLe.js';
1
+ export { N as default } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
package/exports/chain.js CHANGED
@@ -1347,6 +1347,12 @@ class State extends Contract {
1347
1347
  get shouldSync() {
1348
1348
  if (this.#chainSyncing)
1349
1349
  return false;
1350
+ // Check if we have any connected peers with the same version
1351
+ const compatiblePeers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
1352
+ if (compatiblePeers.length === 0) {
1353
+ debug$1('No compatible peers available for sync');
1354
+ return false;
1355
+ }
1350
1356
  if (!this.#chainSyncing ||
1351
1357
  this.#resolveErrored ||
1352
1358
  this.#syncState === 'errored' ||
@@ -1355,6 +1361,25 @@ class State extends Contract {
1355
1361
  return true;
1356
1362
  return false;
1357
1363
  }
1364
+ async #waitForPeers(timeoutMs = 30000) {
1365
+ return new Promise((resolve) => {
1366
+ const checkPeers = () => {
1367
+ const peers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
1368
+ if (peers.length > 0) {
1369
+ resolve(true);
1370
+ }
1371
+ };
1372
+ // Check immediately
1373
+ checkPeers();
1374
+ // Set up interval to check periodically
1375
+ const interval = setInterval(checkPeers, 1000);
1376
+ // Set timeout
1377
+ setTimeout(() => {
1378
+ clearInterval(interval);
1379
+ resolve(false);
1380
+ }, timeoutMs);
1381
+ });
1382
+ }
1358
1383
  async triggerSync() {
1359
1384
  const latest = await this.#getLatestBlock();
1360
1385
  return this.syncChain(latest);
@@ -1414,6 +1439,112 @@ class VersionControl extends State {
1414
1439
  }
1415
1440
  }
1416
1441
 
1442
+ /**
1443
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
1444
+ */
1445
+ class ConnectionMonitor {
1446
+ #isMonitoring = false;
1447
+ #checkInterval = null;
1448
+ #reconnectAttempts = 0;
1449
+ #maxReconnectAttempts = 10;
1450
+ #reconnectDelay = 5000;
1451
+ #healthCheckInterval = 10000;
1452
+ get isMonitoring() {
1453
+ return this.#isMonitoring;
1454
+ }
1455
+ get connectedPeers() {
1456
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
1457
+ }
1458
+ get compatiblePeers() {
1459
+ return this.connectedPeers.filter((peer) => peer.version === this.version);
1460
+ }
1461
+ constructor(version) {
1462
+ this.version = version;
1463
+ }
1464
+ start() {
1465
+ if (this.#isMonitoring)
1466
+ return;
1467
+ this.#isMonitoring = true;
1468
+ console.log('🔄 Starting connection monitor...');
1469
+ this.#checkInterval = setInterval(() => {
1470
+ this.#healthCheck();
1471
+ }, this.#healthCheckInterval);
1472
+ // Initial health check
1473
+ this.#healthCheck();
1474
+ }
1475
+ stop() {
1476
+ if (!this.#isMonitoring)
1477
+ return;
1478
+ this.#isMonitoring = false;
1479
+ if (this.#checkInterval) {
1480
+ clearInterval(this.#checkInterval);
1481
+ this.#checkInterval = null;
1482
+ }
1483
+ console.log('⏹️ Connection monitor stopped');
1484
+ }
1485
+ async #healthCheck() {
1486
+ const connectedPeers = this.connectedPeers;
1487
+ const compatiblePeers = this.compatiblePeers;
1488
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
1489
+ if (connectedPeers.length === 0) {
1490
+ console.warn('⚠️ No peer connections detected');
1491
+ await this.#attemptReconnection();
1492
+ }
1493
+ else if (compatiblePeers.length === 0) {
1494
+ console.warn('⚠️ No compatible peers found');
1495
+ // Could attempt to find compatible peers or trigger version negotiation
1496
+ }
1497
+ else {
1498
+ // Reset reconnect attempts on successful connection
1499
+ this.#reconnectAttempts = 0;
1500
+ }
1501
+ // Publish connection status
1502
+ globalThis.pubsub?.publish('connection-status', {
1503
+ connected: connectedPeers.length,
1504
+ compatible: compatiblePeers.length,
1505
+ healthy: compatiblePeers.length > 0
1506
+ });
1507
+ }
1508
+ async #attemptReconnection() {
1509
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
1510
+ console.error('❌ Max reconnection attempts reached');
1511
+ return;
1512
+ }
1513
+ this.#reconnectAttempts++;
1514
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
1515
+ try {
1516
+ // Try to restart the network
1517
+ if (globalThis.peernet?.start) {
1518
+ await globalThis.peernet.start();
1519
+ }
1520
+ // Wait a bit before next check
1521
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
1522
+ }
1523
+ catch (error) {
1524
+ console.error('❌ Reconnection failed:', error.message);
1525
+ // Exponential backoff
1526
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
1527
+ }
1528
+ }
1529
+ async waitForPeers(timeoutMs = 30000) {
1530
+ return new Promise((resolve) => {
1531
+ const startTime = Date.now();
1532
+ const checkPeers = () => {
1533
+ if (this.compatiblePeers.length > 0) {
1534
+ resolve(true);
1535
+ return;
1536
+ }
1537
+ if (Date.now() - startTime >= timeoutMs) {
1538
+ resolve(false);
1539
+ return;
1540
+ }
1541
+ setTimeout(checkPeers, 1000);
1542
+ };
1543
+ checkPeers();
1544
+ });
1545
+ }
1546
+ }
1547
+
1417
1548
  const debug = globalThis.createDebugger('leofcoin/chain');
1418
1549
  // check if browser or local
1419
1550
  class Chain extends VersionControl {
@@ -1426,6 +1557,10 @@ class Chain extends VersionControl {
1426
1557
  #participants;
1427
1558
  #participating;
1428
1559
  #jail;
1560
+ #peerConnectionRetries;
1561
+ #maxPeerRetries;
1562
+ #peerRetryDelay;
1563
+ #connectionMonitor;
1429
1564
  constructor(config) {
1430
1565
  super(config);
1431
1566
  this.#slotTime = 10000;
@@ -1437,6 +1572,9 @@ class Chain extends VersionControl {
1437
1572
  this.#participants = [];
1438
1573
  this.#participating = false;
1439
1574
  this.#jail = [];
1575
+ this.#peerConnectionRetries = new Map();
1576
+ this.#maxPeerRetries = 5;
1577
+ this.#peerRetryDelay = 5000;
1440
1578
  this.#addTransaction = async (message) => {
1441
1579
  const transaction = new TransactionMessage(message);
1442
1580
  const hash = await transaction.hash();
@@ -1511,6 +1649,7 @@ class Chain extends VersionControl {
1511
1649
  // this.node = await new Node()
1512
1650
  this.#participants = [];
1513
1651
  this.#participating = false;
1652
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
1514
1653
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
1515
1654
  if (!initialized)
1516
1655
  await this.#setup();
@@ -1518,8 +1657,11 @@ class Chain extends VersionControl {
1518
1657
  // this.#state = new State()
1519
1658
  // todo some functions rely on state
1520
1659
  await super.init();
1660
+ // Start connection monitoring
1661
+ this.#connectionMonitor.start();
1521
1662
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
1522
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
1663
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
1664
+ return new BWMessage(bw);
1523
1665
  });
1524
1666
  // await globalThis.peernet.addRequestHandler('peerId', () => {
1525
1667
  // let node =
@@ -1600,7 +1742,7 @@ class Chain extends VersionControl {
1600
1742
  }
1601
1743
  }
1602
1744
  if (this.wantList.length > 0) {
1603
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
1745
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
1604
1746
  for (let i = 0; i < promises.length; i++) {
1605
1747
  const result = promises[i];
1606
1748
  if (result.status === 'fulfilled')
@@ -1927,7 +2069,7 @@ class Chain extends VersionControl {
1927
2069
  * @returns
1928
2070
  */
1929
2071
  internalCall(sender, contract, method, parameters) {
1930
- globalThis.msg = this.#createMessage(sender, contract);
2072
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
1931
2073
  return this.machine.execute(contract, method, parameters);
1932
2074
  }
1933
2075
  /**
@@ -1938,11 +2080,11 @@ class Chain extends VersionControl {
1938
2080
  * @returns
1939
2081
  */
1940
2082
  call(contract, method, parameters) {
1941
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2083
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1942
2084
  return this.machine.execute(contract, method, parameters);
1943
2085
  }
1944
2086
  staticCall(contract, method, parameters) {
1945
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2087
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1946
2088
  return this.machine.get(contract, method, parameters);
1947
2089
  }
1948
2090
  mint(to, amount) {
@@ -1972,6 +2114,27 @@ class Chain extends VersionControl {
1972
2114
  lookup(name) {
1973
2115
  return this.call(addresses.nameService, 'lookup', [name]);
1974
2116
  }
2117
+ #monitorPeerConnections() {
2118
+ setInterval(() => {
2119
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
2120
+ debug(`Connected peers: ${connectedPeers.length}`);
2121
+ if (connectedPeers.length === 0) {
2122
+ debug('No peers connected, attempting to reconnect...');
2123
+ this.#attemptPeerReconnection();
2124
+ }
2125
+ }, 10000); // Check every 10 seconds
2126
+ }
2127
+ async #attemptPeerReconnection() {
2128
+ try {
2129
+ // Try to reconnect to star servers
2130
+ if (globalThis.peernet && globalThis.peernet.start) {
2131
+ await globalThis.peernet.start();
2132
+ }
2133
+ }
2134
+ catch (error) {
2135
+ console.warn('Failed to reconnect to peers:', error.message);
2136
+ }
2137
+ }
1975
2138
  }
1976
2139
 
1977
2140
  export { Chain as default };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
3
+ */
4
+ export default class ConnectionMonitor {
5
+ #private;
6
+ private version;
7
+ get isMonitoring(): boolean;
8
+ get connectedPeers(): import("@netpeer/swarm/peer").default[];
9
+ get compatiblePeers(): import("@netpeer/swarm/peer").default[];
10
+ constructor(version: string);
11
+ start(): void;
12
+ stop(): void;
13
+ waitForPeers(timeoutMs?: number): Promise<boolean>;
14
+ }
@@ -7,7 +7,8 @@ export default class SyncController {
7
7
  get fullyLoaded(): boolean;
8
8
  constructor();
9
9
  /**
10
- * Resolves/rejects a promise or rejects on timeout
10
+ * Resolves/rejects a promise or rejects on timeout with retry logic
11
11
  */
12
- resolve(): void;
12
+ resolve(operation: () => Promise<any>, timeoutMs?: number): Promise<any>;
13
+ stop(): void;
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.7.73",
3
+ "version": "1.7.74",
4
4
  "description": "Official javascript implementation",
5
5
  "private": false,
6
6
  "exports": {