@taphubhq/sdk-core 0.16.0 → 0.16.2

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
@@ -143,6 +143,7 @@ function normaliseAgencyPairs(rows) {
143
143
  pair: row.pair,
144
144
  thumb: row.thumb,
145
145
  ordering: Number(row.ordering),
146
+ status: row.status,
146
147
  maxCoef: Number(row.maxCoef),
147
148
  currentPrice: Number(row.currentPrice),
148
149
  currentVol24h: Number(row.currentVol24h)
@@ -152,7 +153,7 @@ function normaliseAgencyPairs(rows) {
152
153
  // src/modules/agencyPair/queries.ts
153
154
  var FETCH_AGENCY_PAIRS_QUERY = `query FetchAgencyPairs($filter: AgencyPairFilter) {
154
155
  fetchAgencyPairs(filter: $filter) {
155
- gamePairId pair thumb ordering maxCoef currentPrice currentVol24h
156
+ gamePairId pair thumb ordering status maxCoef currentPrice currentVol24h
156
157
  }
157
158
  }`;
158
159
 
@@ -954,6 +955,19 @@ function createMqttTransport(endpoint, opts = {}) {
954
955
  }
955
956
  });
956
957
  client.on("connect", () => {
958
+ const c = client;
959
+ for (const sub of subscriptions.values()) {
960
+ for (const t of sub.topics) c.subscribe(t, { qos: 1 });
961
+ }
962
+ for (const entry of candleSubscriptions.values()) {
963
+ c.subscribe(entry.topic, { qos: 0 });
964
+ }
965
+ for (const entry of statsSubscriptions.values()) {
966
+ c.subscribe(entry.topic, { qos: 0 });
967
+ }
968
+ for (const entry of walletSubscriptions.values()) {
969
+ c.subscribe(entry.topic, { qos: 1 });
970
+ }
957
971
  fireLifecycle({ kind: "connect", rttMs: Date.now() - connectStartedAt });
958
972
  });
959
973
  client.on("reconnect", () => {
@@ -1668,10 +1682,18 @@ function classifyBackendHealth(samples) {
1668
1682
  }
1669
1683
  return "ok";
1670
1684
  }
1671
- var isPoor = (m) => m.rtt > 450 || m.jitter > 150 || m.lossRate > 0.05;
1672
- var canLeavePoor = (m) => m.rtt < 350 && m.jitter < 120 && m.lossRate < 0.03;
1673
- var isFairUpper = (rtt) => rtt > 180;
1674
- var canReachGood = (rtt) => rtt < 120;
1685
+ var RTT_GOOD_TO_FAIR = 180;
1686
+ var RTT_FAIR_TO_GOOD = 120;
1687
+ var RTT_FAIR_TO_POOR = 450;
1688
+ var RTT_POOR_TO_FAIR = 350;
1689
+ var JITTER_POOR = 150;
1690
+ var JITTER_LEAVE_POOR = 120;
1691
+ var LOSS_POOR = 0.05;
1692
+ var LOSS_LEAVE_POOR = 0.03;
1693
+ var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR || m.lossRate > LOSS_POOR;
1694
+ var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR && m.lossRate < LOSS_LEAVE_POOR;
1695
+ var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
1696
+ var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
1675
1697
  function classifyNetworkLevel(metrics, current) {
1676
1698
  if (current === "offline") {
1677
1699
  return isPoor(metrics) ? "poor" : "fair";
@@ -1798,13 +1820,11 @@ var NetworkQualityMonitor = class {
1798
1820
  if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
1799
1821
  bucket.shift();
1800
1822
  }
1801
- if (sample.source !== "connection" && sample.source !== "browser") {
1802
- if (sample.reason === "ok") {
1803
- this.lastSuccessfulHttpAt = sample.ts;
1804
- this.smoother.add(sample.rtt, this.deriveMetrics());
1805
- } else if (sample.reason === "network" || sample.reason === "timeout") {
1806
- this.smoother.add(sample.rtt, this.deriveMetrics());
1807
- }
1823
+ if (sample.reason === "ok" && sample.source !== "connection" && sample.source !== "browser") {
1824
+ this.lastSuccessfulHttpAt = sample.ts;
1825
+ }
1826
+ if (sample.source === "mqtt" && sample.reason === "ok") {
1827
+ this.smoother.add(sample.rtt, this.deriveMetrics());
1808
1828
  }
1809
1829
  this.recompute(prevMqttConnectedOverride);
1810
1830
  }
@@ -1975,17 +1995,15 @@ var NetworkQualityMonitor = class {
1975
1995
  (s) => s.reason === "network" || s.reason === "timeout" || s.reason === "offline"
1976
1996
  ).length;
1977
1997
  const lossRate = total > 0 ? lossCount / total : 0;
1978
- const okRtts = httpSamples.filter(
1979
- (s) => s.reason === "ok" || s.reason === "backend5xx" || s.reason === "backend4xx" || s.reason === "gqlError"
1980
- ).map((s) => s.rtt).filter((r) => Number.isFinite(r));
1998
+ const mqttRtts = samples.filter((s) => s.source === "mqtt" && s.reason === "ok").map((s) => s.rtt).filter((r) => Number.isFinite(r));
1981
1999
  let jitter = 0;
1982
- if (okRtts.length > 1) {
1983
- const mean = okRtts.reduce((a, b) => a + b, 0) / okRtts.length;
1984
- const variance = okRtts.reduce((a, b) => a + (b - mean) ** 2, 0) / okRtts.length;
2000
+ if (mqttRtts.length > 1) {
2001
+ const mean = mqttRtts.reduce((a, b) => a + b, 0) / mqttRtts.length;
2002
+ const variance = mqttRtts.reduce((a, b) => a + (b - mean) ** 2, 0) / mqttRtts.length;
1985
2003
  jitter = Math.sqrt(variance);
1986
2004
  }
1987
2005
  const connectionFallback = samples.filter((s) => s.source === "connection" && Number.isFinite(s.rtt)).slice(-1)[0]?.rtt;
1988
- const emaForLevel = this.smoother.ema > 0 ? this.smoother.ema : okRtts.length > 0 ? okRtts[okRtts.length - 1] ?? 0 : connectionFallback ?? 0;
2006
+ const emaForLevel = this.smoother.ema > 0 ? this.smoother.ema : mqttRtts.length > 0 ? mqttRtts[mqttRtts.length - 1] ?? 0 : connectionFallback ?? 0;
1989
2007
  return { jitter, lossRate, emaForLevel };
1990
2008
  }
1991
2009
  isHardOffline() {
package/dist/index.d.mts CHANGED
@@ -79,6 +79,8 @@ interface AgencyPairStats {
79
79
  thumb: string;
80
80
  /** Lower = earlier in the displayed list. */
81
81
  ordering: number;
82
+ /** Agency pair lifecycle status: "active" | "paused" | "ended". */
83
+ status: AgencyPairStatus;
82
84
  /** config.constraints.maxCoef. */
83
85
  maxCoef: number;
84
86
  /** Latest candle close price; 0 when no candle exists. */
package/dist/index.d.ts CHANGED
@@ -79,6 +79,8 @@ interface AgencyPairStats {
79
79
  thumb: string;
80
80
  /** Lower = earlier in the displayed list. */
81
81
  ordering: number;
82
+ /** Agency pair lifecycle status: "active" | "paused" | "ended". */
83
+ status: AgencyPairStatus;
82
84
  /** config.constraints.maxCoef. */
83
85
  maxCoef: number;
84
86
  /** Latest candle close price; 0 when no candle exists. */
package/dist/index.js CHANGED
@@ -78,6 +78,7 @@ function normaliseAgencyPairs(rows) {
78
78
  pair: row.pair,
79
79
  thumb: row.thumb,
80
80
  ordering: Number(row.ordering),
81
+ status: row.status,
81
82
  maxCoef: Number(row.maxCoef),
82
83
  currentPrice: Number(row.currentPrice),
83
84
  currentVol24h: Number(row.currentVol24h)
@@ -87,7 +88,7 @@ function normaliseAgencyPairs(rows) {
87
88
  // src/modules/agencyPair/queries.ts
88
89
  var FETCH_AGENCY_PAIRS_QUERY = `query FetchAgencyPairs($filter: AgencyPairFilter) {
89
90
  fetchAgencyPairs(filter: $filter) {
90
- gamePairId pair thumb ordering maxCoef currentPrice currentVol24h
91
+ gamePairId pair thumb ordering status maxCoef currentPrice currentVol24h
91
92
  }
92
93
  }`;
93
94
 
@@ -889,6 +890,19 @@ function createMqttTransport(endpoint, opts = {}) {
889
890
  }
890
891
  });
891
892
  client.on("connect", () => {
893
+ const c = client;
894
+ for (const sub of subscriptions.values()) {
895
+ for (const t of sub.topics) c.subscribe(t, { qos: 1 });
896
+ }
897
+ for (const entry of candleSubscriptions.values()) {
898
+ c.subscribe(entry.topic, { qos: 0 });
899
+ }
900
+ for (const entry of statsSubscriptions.values()) {
901
+ c.subscribe(entry.topic, { qos: 0 });
902
+ }
903
+ for (const entry of walletSubscriptions.values()) {
904
+ c.subscribe(entry.topic, { qos: 1 });
905
+ }
892
906
  fireLifecycle({ kind: "connect", rttMs: Date.now() - connectStartedAt });
893
907
  });
894
908
  client.on("reconnect", () => {
@@ -1603,10 +1617,18 @@ function classifyBackendHealth(samples) {
1603
1617
  }
1604
1618
  return "ok";
1605
1619
  }
1606
- var isPoor = (m) => m.rtt > 450 || m.jitter > 150 || m.lossRate > 0.05;
1607
- var canLeavePoor = (m) => m.rtt < 350 && m.jitter < 120 && m.lossRate < 0.03;
1608
- var isFairUpper = (rtt) => rtt > 180;
1609
- var canReachGood = (rtt) => rtt < 120;
1620
+ var RTT_GOOD_TO_FAIR = 180;
1621
+ var RTT_FAIR_TO_GOOD = 120;
1622
+ var RTT_FAIR_TO_POOR = 450;
1623
+ var RTT_POOR_TO_FAIR = 350;
1624
+ var JITTER_POOR = 150;
1625
+ var JITTER_LEAVE_POOR = 120;
1626
+ var LOSS_POOR = 0.05;
1627
+ var LOSS_LEAVE_POOR = 0.03;
1628
+ var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR || m.lossRate > LOSS_POOR;
1629
+ var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR && m.lossRate < LOSS_LEAVE_POOR;
1630
+ var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
1631
+ var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
1610
1632
  function classifyNetworkLevel(metrics, current) {
1611
1633
  if (current === "offline") {
1612
1634
  return isPoor(metrics) ? "poor" : "fair";
@@ -1733,13 +1755,11 @@ var NetworkQualityMonitor = class {
1733
1755
  if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
1734
1756
  bucket.shift();
1735
1757
  }
1736
- if (sample.source !== "connection" && sample.source !== "browser") {
1737
- if (sample.reason === "ok") {
1738
- this.lastSuccessfulHttpAt = sample.ts;
1739
- this.smoother.add(sample.rtt, this.deriveMetrics());
1740
- } else if (sample.reason === "network" || sample.reason === "timeout") {
1741
- this.smoother.add(sample.rtt, this.deriveMetrics());
1742
- }
1758
+ if (sample.reason === "ok" && sample.source !== "connection" && sample.source !== "browser") {
1759
+ this.lastSuccessfulHttpAt = sample.ts;
1760
+ }
1761
+ if (sample.source === "mqtt" && sample.reason === "ok") {
1762
+ this.smoother.add(sample.rtt, this.deriveMetrics());
1743
1763
  }
1744
1764
  this.recompute(prevMqttConnectedOverride);
1745
1765
  }
@@ -1910,17 +1930,15 @@ var NetworkQualityMonitor = class {
1910
1930
  (s) => s.reason === "network" || s.reason === "timeout" || s.reason === "offline"
1911
1931
  ).length;
1912
1932
  const lossRate = total > 0 ? lossCount / total : 0;
1913
- const okRtts = httpSamples.filter(
1914
- (s) => s.reason === "ok" || s.reason === "backend5xx" || s.reason === "backend4xx" || s.reason === "gqlError"
1915
- ).map((s) => s.rtt).filter((r) => Number.isFinite(r));
1933
+ const mqttRtts = samples.filter((s) => s.source === "mqtt" && s.reason === "ok").map((s) => s.rtt).filter((r) => Number.isFinite(r));
1916
1934
  let jitter = 0;
1917
- if (okRtts.length > 1) {
1918
- const mean = okRtts.reduce((a, b) => a + b, 0) / okRtts.length;
1919
- const variance = okRtts.reduce((a, b) => a + (b - mean) ** 2, 0) / okRtts.length;
1935
+ if (mqttRtts.length > 1) {
1936
+ const mean = mqttRtts.reduce((a, b) => a + b, 0) / mqttRtts.length;
1937
+ const variance = mqttRtts.reduce((a, b) => a + (b - mean) ** 2, 0) / mqttRtts.length;
1920
1938
  jitter = Math.sqrt(variance);
1921
1939
  }
1922
1940
  const connectionFallback = samples.filter((s) => s.source === "connection" && Number.isFinite(s.rtt)).slice(-1)[0]?.rtt;
1923
- const emaForLevel = this.smoother.ema > 0 ? this.smoother.ema : okRtts.length > 0 ? okRtts[okRtts.length - 1] ?? 0 : connectionFallback ?? 0;
1941
+ const emaForLevel = this.smoother.ema > 0 ? this.smoother.ema : mqttRtts.length > 0 ? mqttRtts[mqttRtts.length - 1] ?? 0 : connectionFallback ?? 0;
1924
1942
  return { jitter, lossRate, emaForLevel };
1925
1943
  }
1926
1944
  isHardOffline() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taphubhq/sdk-core",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "Core SDK for building on the TabHub platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",