ton-provider-system 0.1.8 → 0.1.9

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/index.cjs CHANGED
@@ -952,6 +952,8 @@ var HealthChecker = class {
952
952
  const existing = this.results.get(key);
953
953
  const result = existing ? {
954
954
  ...existing,
955
+ success: false,
956
+ // CRITICAL: Always set success: false for degraded providers
955
957
  status: "degraded",
956
958
  error: error || "Marked as degraded",
957
959
  lastTested: /* @__PURE__ */ new Date()
@@ -1572,6 +1574,8 @@ var ProviderSelector = class {
1572
1574
  this.autoSelect = true;
1573
1575
  this.customEndpoint = null;
1574
1576
  this.bestProviderByNetwork = /* @__PURE__ */ new Map();
1577
+ // Track currently active provider per network (the one actually being used)
1578
+ this.activeProviderByNetwork = /* @__PURE__ */ new Map();
1575
1579
  this.registry = registry;
1576
1580
  this.healthChecker = healthChecker;
1577
1581
  this.config = { ...DEFAULT_CONFIG2, ...config };
@@ -1590,6 +1594,7 @@ var ProviderSelector = class {
1590
1594
  if (!this.autoSelect && this.selectedProviderId) {
1591
1595
  const provider = this.registry.getProvider(this.selectedProviderId);
1592
1596
  if (provider && provider.network === network) {
1597
+ this.activeProviderByNetwork.set(network, provider.id);
1593
1598
  return provider;
1594
1599
  }
1595
1600
  this.logger.warn(
@@ -1600,8 +1605,13 @@ var ProviderSelector = class {
1600
1605
  if (cachedBestId) {
1601
1606
  const cached = this.registry.getProvider(cachedBestId);
1602
1607
  const health = this.healthChecker.getResult(cachedBestId, network);
1603
- if (cached && health && health.success !== false && this.config.minStatus.includes(health.status)) {
1608
+ if (cached && health && health.success !== false && health.success !== void 0 && // Explicitly check for undefined
1609
+ this.config.minStatus.includes(health.status)) {
1610
+ this.activeProviderByNetwork.set(network, cachedBestId);
1604
1611
  return cached;
1612
+ } else {
1613
+ this.bestProviderByNetwork.delete(network);
1614
+ this.activeProviderByNetwork.delete(network);
1605
1615
  }
1606
1616
  }
1607
1617
  return this.findBestProvider(network);
@@ -1623,10 +1633,17 @@ var ProviderSelector = class {
1623
1633
  const defaults = this.registry.getDefaultOrderForNetwork(network);
1624
1634
  for (const defaultProvider of defaults) {
1625
1635
  const health = this.healthChecker.getResult(defaultProvider.id, network);
1626
- if (!health || health.status === "untested" || health.success === true) {
1636
+ if (!health || health.status === "untested") {
1637
+ this.logger.warn(
1638
+ `No healthy providers for ${network}, using untested default: ${defaultProvider.id}`
1639
+ );
1640
+ this.activeProviderByNetwork.set(network, defaultProvider.id);
1641
+ return defaultProvider;
1642
+ } else if (health.success === true) {
1627
1643
  this.logger.warn(
1628
1644
  `No healthy providers for ${network}, using default: ${defaultProvider.id}`
1629
1645
  );
1646
+ this.activeProviderByNetwork.set(network, defaultProvider.id);
1630
1647
  return defaultProvider;
1631
1648
  }
1632
1649
  }
@@ -1636,6 +1653,7 @@ var ProviderSelector = class {
1636
1653
  this.logger.warn(
1637
1654
  `No tested healthy providers for ${network}, using untested: ${provider.id}`
1638
1655
  );
1656
+ this.activeProviderByNetwork.set(network, provider.id);
1639
1657
  return provider;
1640
1658
  }
1641
1659
  }
@@ -1646,10 +1664,12 @@ var ProviderSelector = class {
1646
1664
  const bestHealth = this.healthChecker.getResult(best.id, network);
1647
1665
  if (bestHealth && bestHealth.success === true) {
1648
1666
  this.bestProviderByNetwork.set(network, best.id);
1667
+ this.activeProviderByNetwork.set(network, best.id);
1649
1668
  this.logger.debug(
1650
1669
  `Best provider for ${network}: ${best.id} (score: ${scored[0].score.toFixed(2)})`
1651
1670
  );
1652
1671
  } else {
1672
+ this.activeProviderByNetwork.set(network, best.id);
1653
1673
  this.logger.debug(
1654
1674
  `Best provider for ${network}: ${best.id} (score: ${scored[0].score.toFixed(2)}, untested)`
1655
1675
  );
@@ -1789,9 +1809,16 @@ var ProviderSelector = class {
1789
1809
  }
1790
1810
  /**
1791
1811
  * Clear cached best providers (forces recalculation)
1812
+ * @param network - Optional network to clear cache for. If not provided, clears all networks.
1792
1813
  */
1793
- clearCache() {
1794
- this.bestProviderByNetwork.clear();
1814
+ clearCache(network) {
1815
+ if (network) {
1816
+ this.bestProviderByNetwork.delete(network);
1817
+ this.activeProviderByNetwork.delete(network);
1818
+ } else {
1819
+ this.bestProviderByNetwork.clear();
1820
+ this.activeProviderByNetwork.clear();
1821
+ }
1795
1822
  }
1796
1823
  /**
1797
1824
  * Update best provider after health check
@@ -1806,8 +1833,16 @@ var ProviderSelector = class {
1806
1833
  if (this.bestProviderByNetwork.get(network) === providerId) {
1807
1834
  this.bestProviderByNetwork.delete(network);
1808
1835
  }
1836
+ this.activeProviderByNetwork.delete(network);
1809
1837
  return this.getNextProvider(network, [providerId]);
1810
1838
  }
1839
+ /**
1840
+ * Get the currently active provider ID for a network
1841
+ * (the one that was last selected and is being used)
1842
+ */
1843
+ getActiveProviderId(network) {
1844
+ return this.activeProviderByNetwork.get(network) || null;
1845
+ }
1811
1846
  // ========================================================================
1812
1847
  // Info
1813
1848
  // ========================================================================
@@ -2044,6 +2079,7 @@ var _ProviderManager = class _ProviderManager {
2044
2079
  this.options.logger.warn("No providers available, using fallback");
2045
2080
  return this.getFallbackEndpoint();
2046
2081
  }
2082
+ this.selector.getActiveProviderId(this.network) || this.selector.getBestProvider(this.network);
2047
2083
  if (provider.isDynamic && provider.type === "orbs") {
2048
2084
  try {
2049
2085
  const { getHttpEndpoint } = await import('@orbs-network/ton-access');
@@ -2059,9 +2095,14 @@ var _ProviderManager = class _ProviderManager {
2059
2095
  * Get endpoint with rate limiting
2060
2096
  *
2061
2097
  * Waits for rate limit token before returning endpoint.
2098
+ *
2099
+ * @param forceRefresh - If true, clears cache and forces re-selection
2062
2100
  */
2063
- async getEndpointWithRateLimit(timeoutMs) {
2101
+ async getEndpointWithRateLimit(timeoutMs, forceRefresh = false) {
2064
2102
  this.ensureInitialized();
2103
+ if (forceRefresh) {
2104
+ this.selector.clearCache(this.network);
2105
+ }
2065
2106
  const provider = this.selector.getBestProvider(this.network);
2066
2107
  if (!provider) {
2067
2108
  return this.getFallbackEndpoint();
@@ -2113,7 +2154,14 @@ var _ProviderManager = class _ProviderManager {
2113
2154
  */
2114
2155
  reportError(error) {
2115
2156
  if (!this.initialized || !this.network) return;
2116
- const provider = this.selector.getBestProvider(this.network);
2157
+ const activeProviderId = this.selector.getActiveProviderId(this.network);
2158
+ let provider = null;
2159
+ if (activeProviderId) {
2160
+ provider = this.registry.getProvider(activeProviderId) || null;
2161
+ }
2162
+ if (!provider) {
2163
+ provider = this.selector.getBestProvider(this.network);
2164
+ }
2117
2165
  if (!provider) return;
2118
2166
  const errorMsg = error instanceof Error ? error.message : String(error);
2119
2167
  const errorMsgLower = errorMsg.toLowerCase();
@@ -2132,6 +2180,7 @@ var _ProviderManager = class _ProviderManager {
2132
2180
  this.rateLimiter.reportError(provider.id);
2133
2181
  this.healthChecker.markDegraded(provider.id, this.network, errorMsg);
2134
2182
  }
2183
+ this.selector.clearCache(this.network);
2135
2184
  this.selector.handleProviderFailure(provider.id, this.network);
2136
2185
  this.notifyListeners();
2137
2186
  }