@taphubhq/sdk-core 0.23.0 → 0.23.1

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
@@ -1828,31 +1828,11 @@ function classifyBackendHealth(samples) {
1828
1828
  }
1829
1829
  return "ok";
1830
1830
  }
1831
- var RTT_GOOD_TO_FAIR = 180;
1832
- var RTT_FAIR_TO_GOOD = 120;
1833
- var RTT_FAIR_TO_POOR = 450;
1834
- var RTT_POOR_TO_FAIR = 350;
1835
- var JITTER_POOR = 150;
1836
- var JITTER_LEAVE_POOR = 120;
1837
- var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR;
1838
- var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR;
1839
- var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
1840
- var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
1841
- function classifyNetworkLevel(metrics, current) {
1842
- if (current === "offline") {
1843
- return isPoor(metrics) ? "poor" : "fair";
1844
- }
1845
- if (current === "good") {
1846
- if (isPoor(metrics)) return "fair";
1847
- if (isFairUpper(metrics.rtt)) return "fair";
1848
- return "good";
1849
- }
1850
- if (current === "fair") {
1851
- if (isPoor(metrics)) return "poor";
1852
- if (canReachGood(metrics.rtt)) return "good";
1853
- return "fair";
1854
- }
1855
- if (canLeavePoor(metrics)) return "fair";
1831
+ var GOOD_MAX_MS = 150;
1832
+ var FAIR_MAX_MS = 400;
1833
+ function classifyNetworkLevel(rtt) {
1834
+ if (rtt <= GOOD_MAX_MS) return "good";
1835
+ if (rtt <= FAIR_MAX_MS) return "fair";
1856
1836
  return "poor";
1857
1837
  }
1858
1838
 
@@ -1875,24 +1855,30 @@ var RttSmoother = class {
1875
1855
  candidateCount = 0;
1876
1856
  overrideOffline = false;
1877
1857
  consecutiveOutliers = 0;
1878
- add(rtt, metrics) {
1858
+ add(rtt) {
1879
1859
  if (this.ema > 0 && rtt > OUTLIER_MULTIPLIER * this.ema) {
1880
1860
  this.consecutiveOutliers += 1;
1881
1861
  if (this.consecutiveOutliers < 2) return;
1882
1862
  } else {
1883
1863
  this.consecutiveOutliers = 0;
1884
1864
  }
1885
- this.ema = this.ema === 0 ? rtt : EMA_ALPHA * rtt + (1 - EMA_ALPHA) * this.ema;
1886
- const next = classifyNetworkLevel({ rtt, jitter: metrics.jitter }, this.committed);
1887
- if (next === this.candidate) {
1888
- this.candidateCount += 1;
1889
- } else {
1865
+ const coldStart = this.ema === 0;
1866
+ this.ema = coldStart ? rtt : EMA_ALPHA * rtt + (1 - EMA_ALPHA) * this.ema;
1867
+ const next = classifyNetworkLevel(this.ema);
1868
+ if (coldStart) {
1869
+ this.committed = next;
1890
1870
  this.candidate = next;
1891
1871
  this.candidateCount = 1;
1892
- }
1893
- const required = this.requiredSamplesFor(next);
1894
- if (this.candidateCount >= required) {
1895
- this.committed = next;
1872
+ } else {
1873
+ if (next === this.candidate) {
1874
+ this.candidateCount += 1;
1875
+ } else {
1876
+ this.candidate = next;
1877
+ this.candidateCount = 1;
1878
+ }
1879
+ if (this.candidateCount >= this.requiredSamplesFor(next)) {
1880
+ this.committed = next;
1881
+ }
1896
1882
  }
1897
1883
  this.level = this.overrideOffline ? "offline" : this.committed;
1898
1884
  }
@@ -1960,9 +1946,6 @@ var NetworkQualityMonitor = class {
1960
1946
  if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
1961
1947
  bucket.shift();
1962
1948
  }
1963
- if (sample.source === "mqtt" && sample.reason === "ok") {
1964
- this.smoother.add(sample.rtt, this.deriveMetrics());
1965
- }
1966
1949
  this.recompute(prevMqttConnectedOverride);
1967
1950
  }
1968
1951
  seedFromConnection(seed) {
@@ -1996,6 +1979,7 @@ var NetworkQualityMonitor = class {
1996
1979
  this.recompute(prevMqttConnected);
1997
1980
  }
1998
1981
  notifyMqttPing(rttMs) {
1982
+ this.smoother.add(rttMs);
1999
1983
  this.addSample({
2000
1984
  ts: this.now(),
2001
1985
  rtt: rttMs,
@@ -2093,10 +2077,7 @@ var NetworkQualityMonitor = class {
2093
2077
  const httpSamples = effectiveSamples.filter((s) => isHttpSource(s.source));
2094
2078
  const backend = classifyBackendHealth(httpSamples);
2095
2079
  const metrics = this.deriveMetricsFrom(effectiveSamples);
2096
- const candidate = classifyNetworkLevel(
2097
- { rtt: metrics.emaForLevel, jitter: metrics.jitter },
2098
- this.committedNetwork
2099
- );
2080
+ const candidate = classifyNetworkLevel(metrics.emaForLevel);
2100
2081
  let nextNetwork = this.smoother.level;
2101
2082
  if (effectiveSamples.length === 0) {
2102
2083
  nextNetwork = this.committedNetwork;
@@ -2121,9 +2102,6 @@ var NetworkQualityMonitor = class {
2121
2102
  this.bus.emit("network:change", { previous: prev, current });
2122
2103
  }
2123
2104
  }
2124
- deriveMetrics() {
2125
- return this.deriveMetricsFrom(this.allHttpAndMqttSamples());
2126
- }
2127
2105
  deriveMetricsFrom(samples) {
2128
2106
  const httpSamples = samples.filter((s) => isHttpSource(s.source));
2129
2107
  const total = httpSamples.length;
package/dist/index.d.mts CHANGED
@@ -1052,7 +1052,6 @@ declare class NetworkQualityMonitor {
1052
1052
  private detachBrowserListeners;
1053
1053
  private pruneWindow;
1054
1054
  private recompute;
1055
- private deriveMetrics;
1056
1055
  private deriveMetricsFrom;
1057
1056
  private isHardOffline;
1058
1057
  private allHttpAndMqttSamples;
package/dist/index.d.ts CHANGED
@@ -1052,7 +1052,6 @@ declare class NetworkQualityMonitor {
1052
1052
  private detachBrowserListeners;
1053
1053
  private pruneWindow;
1054
1054
  private recompute;
1055
- private deriveMetrics;
1056
1055
  private deriveMetricsFrom;
1057
1056
  private isHardOffline;
1058
1057
  private allHttpAndMqttSamples;
package/dist/index.js CHANGED
@@ -1763,31 +1763,11 @@ function classifyBackendHealth(samples) {
1763
1763
  }
1764
1764
  return "ok";
1765
1765
  }
1766
- var RTT_GOOD_TO_FAIR = 180;
1767
- var RTT_FAIR_TO_GOOD = 120;
1768
- var RTT_FAIR_TO_POOR = 450;
1769
- var RTT_POOR_TO_FAIR = 350;
1770
- var JITTER_POOR = 150;
1771
- var JITTER_LEAVE_POOR = 120;
1772
- var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR;
1773
- var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR;
1774
- var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
1775
- var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
1776
- function classifyNetworkLevel(metrics, current) {
1777
- if (current === "offline") {
1778
- return isPoor(metrics) ? "poor" : "fair";
1779
- }
1780
- if (current === "good") {
1781
- if (isPoor(metrics)) return "fair";
1782
- if (isFairUpper(metrics.rtt)) return "fair";
1783
- return "good";
1784
- }
1785
- if (current === "fair") {
1786
- if (isPoor(metrics)) return "poor";
1787
- if (canReachGood(metrics.rtt)) return "good";
1788
- return "fair";
1789
- }
1790
- if (canLeavePoor(metrics)) return "fair";
1766
+ var GOOD_MAX_MS = 150;
1767
+ var FAIR_MAX_MS = 400;
1768
+ function classifyNetworkLevel(rtt) {
1769
+ if (rtt <= GOOD_MAX_MS) return "good";
1770
+ if (rtt <= FAIR_MAX_MS) return "fair";
1791
1771
  return "poor";
1792
1772
  }
1793
1773
 
@@ -1810,24 +1790,30 @@ var RttSmoother = class {
1810
1790
  candidateCount = 0;
1811
1791
  overrideOffline = false;
1812
1792
  consecutiveOutliers = 0;
1813
- add(rtt, metrics) {
1793
+ add(rtt) {
1814
1794
  if (this.ema > 0 && rtt > OUTLIER_MULTIPLIER * this.ema) {
1815
1795
  this.consecutiveOutliers += 1;
1816
1796
  if (this.consecutiveOutliers < 2) return;
1817
1797
  } else {
1818
1798
  this.consecutiveOutliers = 0;
1819
1799
  }
1820
- this.ema = this.ema === 0 ? rtt : EMA_ALPHA * rtt + (1 - EMA_ALPHA) * this.ema;
1821
- const next = classifyNetworkLevel({ rtt, jitter: metrics.jitter }, this.committed);
1822
- if (next === this.candidate) {
1823
- this.candidateCount += 1;
1824
- } else {
1800
+ const coldStart = this.ema === 0;
1801
+ this.ema = coldStart ? rtt : EMA_ALPHA * rtt + (1 - EMA_ALPHA) * this.ema;
1802
+ const next = classifyNetworkLevel(this.ema);
1803
+ if (coldStart) {
1804
+ this.committed = next;
1825
1805
  this.candidate = next;
1826
1806
  this.candidateCount = 1;
1827
- }
1828
- const required = this.requiredSamplesFor(next);
1829
- if (this.candidateCount >= required) {
1830
- this.committed = next;
1807
+ } else {
1808
+ if (next === this.candidate) {
1809
+ this.candidateCount += 1;
1810
+ } else {
1811
+ this.candidate = next;
1812
+ this.candidateCount = 1;
1813
+ }
1814
+ if (this.candidateCount >= this.requiredSamplesFor(next)) {
1815
+ this.committed = next;
1816
+ }
1831
1817
  }
1832
1818
  this.level = this.overrideOffline ? "offline" : this.committed;
1833
1819
  }
@@ -1895,9 +1881,6 @@ var NetworkQualityMonitor = class {
1895
1881
  if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
1896
1882
  bucket.shift();
1897
1883
  }
1898
- if (sample.source === "mqtt" && sample.reason === "ok") {
1899
- this.smoother.add(sample.rtt, this.deriveMetrics());
1900
- }
1901
1884
  this.recompute(prevMqttConnectedOverride);
1902
1885
  }
1903
1886
  seedFromConnection(seed) {
@@ -1931,6 +1914,7 @@ var NetworkQualityMonitor = class {
1931
1914
  this.recompute(prevMqttConnected);
1932
1915
  }
1933
1916
  notifyMqttPing(rttMs) {
1917
+ this.smoother.add(rttMs);
1934
1918
  this.addSample({
1935
1919
  ts: this.now(),
1936
1920
  rtt: rttMs,
@@ -2028,10 +2012,7 @@ var NetworkQualityMonitor = class {
2028
2012
  const httpSamples = effectiveSamples.filter((s) => isHttpSource(s.source));
2029
2013
  const backend = classifyBackendHealth(httpSamples);
2030
2014
  const metrics = this.deriveMetricsFrom(effectiveSamples);
2031
- const candidate = classifyNetworkLevel(
2032
- { rtt: metrics.emaForLevel, jitter: metrics.jitter },
2033
- this.committedNetwork
2034
- );
2015
+ const candidate = classifyNetworkLevel(metrics.emaForLevel);
2035
2016
  let nextNetwork = this.smoother.level;
2036
2017
  if (effectiveSamples.length === 0) {
2037
2018
  nextNetwork = this.committedNetwork;
@@ -2056,9 +2037,6 @@ var NetworkQualityMonitor = class {
2056
2037
  this.bus.emit("network:change", { previous: prev, current });
2057
2038
  }
2058
2039
  }
2059
- deriveMetrics() {
2060
- return this.deriveMetricsFrom(this.allHttpAndMqttSamples());
2061
- }
2062
2040
  deriveMetricsFrom(samples) {
2063
2041
  const httpSamples = samples.filter((s) => isHttpSource(s.source));
2064
2042
  const total = httpSamples.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taphubhq/sdk-core",
3
- "version": "0.23.0",
3
+ "version": "0.23.1",
4
4
  "description": "Core SDK for building on the TabHub platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",