@taphubhq/sdk-core 0.22.3 → 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 +33 -46
- package/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +33 -46
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -863,7 +863,15 @@ function normaliseGameConfig(node) {
|
|
|
863
863
|
constraints: normaliseConstraints(node.constraints),
|
|
864
864
|
acceptableBids: node.acceptableBids,
|
|
865
865
|
minBidAmount: node.minBidAmount,
|
|
866
|
-
maxBidAmount: node.maxBidAmount
|
|
866
|
+
maxBidAmount: node.maxBidAmount,
|
|
867
|
+
// Effective cancel policy. Distinguish three states so consumers can apply
|
|
868
|
+
// the right default:
|
|
869
|
+
// undefined → server omitted the field (older server) → use platform default
|
|
870
|
+
// 0 → builder explicitly disabled cancel → keep 0 (cancel OFF)
|
|
871
|
+
// > 0 → builder/effective threshold
|
|
872
|
+
// (null from the wire becomes undefined, NOT 0, so "not sent" ≠ "disabled".)
|
|
873
|
+
bidCancelRefundRate: node.bidCancelRefundRate ?? void 0,
|
|
874
|
+
bidCancelMinSeconds: node.bidCancelMinSeconds ?? void 0
|
|
867
875
|
};
|
|
868
876
|
}
|
|
869
877
|
function normaliseGridConfig(node) {
|
|
@@ -925,6 +933,7 @@ var PAIR_QUERY = `query AgencyPair($pairId: ID!) {
|
|
|
925
933
|
gridConfig { cellSizeTime cellSizeValue candleSize baseline baselineTime }
|
|
926
934
|
constraints { minBetTime maxBetTime slippage priceMinRange priceMaxRange coefMults maxCoef }
|
|
927
935
|
acceptableBids minBidAmount maxBidAmount
|
|
936
|
+
bidCancelRefundRate bidCancelMinSeconds
|
|
928
937
|
}
|
|
929
938
|
}
|
|
930
939
|
}`;
|
|
@@ -1819,31 +1828,11 @@ function classifyBackendHealth(samples) {
|
|
|
1819
1828
|
}
|
|
1820
1829
|
return "ok";
|
|
1821
1830
|
}
|
|
1822
|
-
var
|
|
1823
|
-
var
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
var JITTER_LEAVE_POOR = 120;
|
|
1828
|
-
var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR;
|
|
1829
|
-
var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR;
|
|
1830
|
-
var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
|
|
1831
|
-
var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
|
|
1832
|
-
function classifyNetworkLevel(metrics, current) {
|
|
1833
|
-
if (current === "offline") {
|
|
1834
|
-
return isPoor(metrics) ? "poor" : "fair";
|
|
1835
|
-
}
|
|
1836
|
-
if (current === "good") {
|
|
1837
|
-
if (isPoor(metrics)) return "fair";
|
|
1838
|
-
if (isFairUpper(metrics.rtt)) return "fair";
|
|
1839
|
-
return "good";
|
|
1840
|
-
}
|
|
1841
|
-
if (current === "fair") {
|
|
1842
|
-
if (isPoor(metrics)) return "poor";
|
|
1843
|
-
if (canReachGood(metrics.rtt)) return "good";
|
|
1844
|
-
return "fair";
|
|
1845
|
-
}
|
|
1846
|
-
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";
|
|
1847
1836
|
return "poor";
|
|
1848
1837
|
}
|
|
1849
1838
|
|
|
@@ -1866,24 +1855,30 @@ var RttSmoother = class {
|
|
|
1866
1855
|
candidateCount = 0;
|
|
1867
1856
|
overrideOffline = false;
|
|
1868
1857
|
consecutiveOutliers = 0;
|
|
1869
|
-
add(rtt
|
|
1858
|
+
add(rtt) {
|
|
1870
1859
|
if (this.ema > 0 && rtt > OUTLIER_MULTIPLIER * this.ema) {
|
|
1871
1860
|
this.consecutiveOutliers += 1;
|
|
1872
1861
|
if (this.consecutiveOutliers < 2) return;
|
|
1873
1862
|
} else {
|
|
1874
1863
|
this.consecutiveOutliers = 0;
|
|
1875
1864
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
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;
|
|
1881
1870
|
this.candidate = next;
|
|
1882
1871
|
this.candidateCount = 1;
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
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
|
+
}
|
|
1887
1882
|
}
|
|
1888
1883
|
this.level = this.overrideOffline ? "offline" : this.committed;
|
|
1889
1884
|
}
|
|
@@ -1951,9 +1946,6 @@ var NetworkQualityMonitor = class {
|
|
|
1951
1946
|
if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
|
|
1952
1947
|
bucket.shift();
|
|
1953
1948
|
}
|
|
1954
|
-
if (sample.source === "mqtt" && sample.reason === "ok") {
|
|
1955
|
-
this.smoother.add(sample.rtt, this.deriveMetrics());
|
|
1956
|
-
}
|
|
1957
1949
|
this.recompute(prevMqttConnectedOverride);
|
|
1958
1950
|
}
|
|
1959
1951
|
seedFromConnection(seed) {
|
|
@@ -1987,6 +1979,7 @@ var NetworkQualityMonitor = class {
|
|
|
1987
1979
|
this.recompute(prevMqttConnected);
|
|
1988
1980
|
}
|
|
1989
1981
|
notifyMqttPing(rttMs) {
|
|
1982
|
+
this.smoother.add(rttMs);
|
|
1990
1983
|
this.addSample({
|
|
1991
1984
|
ts: this.now(),
|
|
1992
1985
|
rtt: rttMs,
|
|
@@ -2084,10 +2077,7 @@ var NetworkQualityMonitor = class {
|
|
|
2084
2077
|
const httpSamples = effectiveSamples.filter((s) => isHttpSource(s.source));
|
|
2085
2078
|
const backend = classifyBackendHealth(httpSamples);
|
|
2086
2079
|
const metrics = this.deriveMetricsFrom(effectiveSamples);
|
|
2087
|
-
const candidate = classifyNetworkLevel(
|
|
2088
|
-
{ rtt: metrics.emaForLevel, jitter: metrics.jitter },
|
|
2089
|
-
this.committedNetwork
|
|
2090
|
-
);
|
|
2080
|
+
const candidate = classifyNetworkLevel(metrics.emaForLevel);
|
|
2091
2081
|
let nextNetwork = this.smoother.level;
|
|
2092
2082
|
if (effectiveSamples.length === 0) {
|
|
2093
2083
|
nextNetwork = this.committedNetwork;
|
|
@@ -2112,9 +2102,6 @@ var NetworkQualityMonitor = class {
|
|
|
2112
2102
|
this.bus.emit("network:change", { previous: prev, current });
|
|
2113
2103
|
}
|
|
2114
2104
|
}
|
|
2115
|
-
deriveMetrics() {
|
|
2116
|
-
return this.deriveMetricsFrom(this.allHttpAndMqttSamples());
|
|
2117
|
-
}
|
|
2118
2105
|
deriveMetricsFrom(samples) {
|
|
2119
2106
|
const httpSamples = samples.filter((s) => isHttpSource(s.source));
|
|
2120
2107
|
const total = httpSamples.length;
|
package/dist/index.d.mts
CHANGED
|
@@ -500,6 +500,19 @@ interface GameConfig {
|
|
|
500
500
|
acceptableBids: number[];
|
|
501
501
|
minBidAmount: number;
|
|
502
502
|
maxBidAmount: number;
|
|
503
|
+
/**
|
|
504
|
+
* Effective cancel policy — the values the server's cancel engine actually
|
|
505
|
+
* enforces (per-game config, falling back to platform defaults). Use these
|
|
506
|
+
* to drive the Cancel button: a bid is cancellable while
|
|
507
|
+
* `time2 - now > bidCancelMinSeconds`; on cancel the player is refunded
|
|
508
|
+
* `amount * bidCancelRefundRate`.
|
|
509
|
+
*
|
|
510
|
+
* Optional for backward compatibility: a server (or a manually-constructed
|
|
511
|
+
* config) that predates this field omits it. normalisePair fills 0 from the
|
|
512
|
+
* wire; consumers should treat `undefined`/`0` as "use the platform default".
|
|
513
|
+
*/
|
|
514
|
+
bidCancelRefundRate?: number;
|
|
515
|
+
bidCancelMinSeconds?: number;
|
|
503
516
|
}
|
|
504
517
|
interface GridConfig {
|
|
505
518
|
cellSizeTime: number;
|
|
@@ -1039,7 +1052,6 @@ declare class NetworkQualityMonitor {
|
|
|
1039
1052
|
private detachBrowserListeners;
|
|
1040
1053
|
private pruneWindow;
|
|
1041
1054
|
private recompute;
|
|
1042
|
-
private deriveMetrics;
|
|
1043
1055
|
private deriveMetricsFrom;
|
|
1044
1056
|
private isHardOffline;
|
|
1045
1057
|
private allHttpAndMqttSamples;
|
package/dist/index.d.ts
CHANGED
|
@@ -500,6 +500,19 @@ interface GameConfig {
|
|
|
500
500
|
acceptableBids: number[];
|
|
501
501
|
minBidAmount: number;
|
|
502
502
|
maxBidAmount: number;
|
|
503
|
+
/**
|
|
504
|
+
* Effective cancel policy — the values the server's cancel engine actually
|
|
505
|
+
* enforces (per-game config, falling back to platform defaults). Use these
|
|
506
|
+
* to drive the Cancel button: a bid is cancellable while
|
|
507
|
+
* `time2 - now > bidCancelMinSeconds`; on cancel the player is refunded
|
|
508
|
+
* `amount * bidCancelRefundRate`.
|
|
509
|
+
*
|
|
510
|
+
* Optional for backward compatibility: a server (or a manually-constructed
|
|
511
|
+
* config) that predates this field omits it. normalisePair fills 0 from the
|
|
512
|
+
* wire; consumers should treat `undefined`/`0` as "use the platform default".
|
|
513
|
+
*/
|
|
514
|
+
bidCancelRefundRate?: number;
|
|
515
|
+
bidCancelMinSeconds?: number;
|
|
503
516
|
}
|
|
504
517
|
interface GridConfig {
|
|
505
518
|
cellSizeTime: number;
|
|
@@ -1039,7 +1052,6 @@ declare class NetworkQualityMonitor {
|
|
|
1039
1052
|
private detachBrowserListeners;
|
|
1040
1053
|
private pruneWindow;
|
|
1041
1054
|
private recompute;
|
|
1042
|
-
private deriveMetrics;
|
|
1043
1055
|
private deriveMetricsFrom;
|
|
1044
1056
|
private isHardOffline;
|
|
1045
1057
|
private allHttpAndMqttSamples;
|
package/dist/index.js
CHANGED
|
@@ -798,7 +798,15 @@ function normaliseGameConfig(node) {
|
|
|
798
798
|
constraints: normaliseConstraints(node.constraints),
|
|
799
799
|
acceptableBids: node.acceptableBids,
|
|
800
800
|
minBidAmount: node.minBidAmount,
|
|
801
|
-
maxBidAmount: node.maxBidAmount
|
|
801
|
+
maxBidAmount: node.maxBidAmount,
|
|
802
|
+
// Effective cancel policy. Distinguish three states so consumers can apply
|
|
803
|
+
// the right default:
|
|
804
|
+
// undefined → server omitted the field (older server) → use platform default
|
|
805
|
+
// 0 → builder explicitly disabled cancel → keep 0 (cancel OFF)
|
|
806
|
+
// > 0 → builder/effective threshold
|
|
807
|
+
// (null from the wire becomes undefined, NOT 0, so "not sent" ≠ "disabled".)
|
|
808
|
+
bidCancelRefundRate: node.bidCancelRefundRate ?? void 0,
|
|
809
|
+
bidCancelMinSeconds: node.bidCancelMinSeconds ?? void 0
|
|
802
810
|
};
|
|
803
811
|
}
|
|
804
812
|
function normaliseGridConfig(node) {
|
|
@@ -860,6 +868,7 @@ var PAIR_QUERY = `query AgencyPair($pairId: ID!) {
|
|
|
860
868
|
gridConfig { cellSizeTime cellSizeValue candleSize baseline baselineTime }
|
|
861
869
|
constraints { minBetTime maxBetTime slippage priceMinRange priceMaxRange coefMults maxCoef }
|
|
862
870
|
acceptableBids minBidAmount maxBidAmount
|
|
871
|
+
bidCancelRefundRate bidCancelMinSeconds
|
|
863
872
|
}
|
|
864
873
|
}
|
|
865
874
|
}`;
|
|
@@ -1754,31 +1763,11 @@ function classifyBackendHealth(samples) {
|
|
|
1754
1763
|
}
|
|
1755
1764
|
return "ok";
|
|
1756
1765
|
}
|
|
1757
|
-
var
|
|
1758
|
-
var
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
var JITTER_LEAVE_POOR = 120;
|
|
1763
|
-
var isPoor = (m) => m.rtt > RTT_FAIR_TO_POOR || m.jitter > JITTER_POOR;
|
|
1764
|
-
var canLeavePoor = (m) => m.rtt < RTT_POOR_TO_FAIR && m.jitter < JITTER_LEAVE_POOR;
|
|
1765
|
-
var isFairUpper = (rtt) => rtt > RTT_GOOD_TO_FAIR;
|
|
1766
|
-
var canReachGood = (rtt) => rtt < RTT_FAIR_TO_GOOD;
|
|
1767
|
-
function classifyNetworkLevel(metrics, current) {
|
|
1768
|
-
if (current === "offline") {
|
|
1769
|
-
return isPoor(metrics) ? "poor" : "fair";
|
|
1770
|
-
}
|
|
1771
|
-
if (current === "good") {
|
|
1772
|
-
if (isPoor(metrics)) return "fair";
|
|
1773
|
-
if (isFairUpper(metrics.rtt)) return "fair";
|
|
1774
|
-
return "good";
|
|
1775
|
-
}
|
|
1776
|
-
if (current === "fair") {
|
|
1777
|
-
if (isPoor(metrics)) return "poor";
|
|
1778
|
-
if (canReachGood(metrics.rtt)) return "good";
|
|
1779
|
-
return "fair";
|
|
1780
|
-
}
|
|
1781
|
-
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";
|
|
1782
1771
|
return "poor";
|
|
1783
1772
|
}
|
|
1784
1773
|
|
|
@@ -1801,24 +1790,30 @@ var RttSmoother = class {
|
|
|
1801
1790
|
candidateCount = 0;
|
|
1802
1791
|
overrideOffline = false;
|
|
1803
1792
|
consecutiveOutliers = 0;
|
|
1804
|
-
add(rtt
|
|
1793
|
+
add(rtt) {
|
|
1805
1794
|
if (this.ema > 0 && rtt > OUTLIER_MULTIPLIER * this.ema) {
|
|
1806
1795
|
this.consecutiveOutliers += 1;
|
|
1807
1796
|
if (this.consecutiveOutliers < 2) return;
|
|
1808
1797
|
} else {
|
|
1809
1798
|
this.consecutiveOutliers = 0;
|
|
1810
1799
|
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
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;
|
|
1816
1805
|
this.candidate = next;
|
|
1817
1806
|
this.candidateCount = 1;
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
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
|
+
}
|
|
1822
1817
|
}
|
|
1823
1818
|
this.level = this.overrideOffline ? "offline" : this.committed;
|
|
1824
1819
|
}
|
|
@@ -1886,9 +1881,6 @@ var NetworkQualityMonitor = class {
|
|
|
1886
1881
|
if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
|
|
1887
1882
|
bucket.shift();
|
|
1888
1883
|
}
|
|
1889
|
-
if (sample.source === "mqtt" && sample.reason === "ok") {
|
|
1890
|
-
this.smoother.add(sample.rtt, this.deriveMetrics());
|
|
1891
|
-
}
|
|
1892
1884
|
this.recompute(prevMqttConnectedOverride);
|
|
1893
1885
|
}
|
|
1894
1886
|
seedFromConnection(seed) {
|
|
@@ -1922,6 +1914,7 @@ var NetworkQualityMonitor = class {
|
|
|
1922
1914
|
this.recompute(prevMqttConnected);
|
|
1923
1915
|
}
|
|
1924
1916
|
notifyMqttPing(rttMs) {
|
|
1917
|
+
this.smoother.add(rttMs);
|
|
1925
1918
|
this.addSample({
|
|
1926
1919
|
ts: this.now(),
|
|
1927
1920
|
rtt: rttMs,
|
|
@@ -2019,10 +2012,7 @@ var NetworkQualityMonitor = class {
|
|
|
2019
2012
|
const httpSamples = effectiveSamples.filter((s) => isHttpSource(s.source));
|
|
2020
2013
|
const backend = classifyBackendHealth(httpSamples);
|
|
2021
2014
|
const metrics = this.deriveMetricsFrom(effectiveSamples);
|
|
2022
|
-
const candidate = classifyNetworkLevel(
|
|
2023
|
-
{ rtt: metrics.emaForLevel, jitter: metrics.jitter },
|
|
2024
|
-
this.committedNetwork
|
|
2025
|
-
);
|
|
2015
|
+
const candidate = classifyNetworkLevel(metrics.emaForLevel);
|
|
2026
2016
|
let nextNetwork = this.smoother.level;
|
|
2027
2017
|
if (effectiveSamples.length === 0) {
|
|
2028
2018
|
nextNetwork = this.committedNetwork;
|
|
@@ -2047,9 +2037,6 @@ var NetworkQualityMonitor = class {
|
|
|
2047
2037
|
this.bus.emit("network:change", { previous: prev, current });
|
|
2048
2038
|
}
|
|
2049
2039
|
}
|
|
2050
|
-
deriveMetrics() {
|
|
2051
|
-
return this.deriveMetricsFrom(this.allHttpAndMqttSamples());
|
|
2052
|
-
}
|
|
2053
2040
|
deriveMetricsFrom(samples) {
|
|
2054
2041
|
const httpSamples = samples.filter((s) => isHttpSource(s.source));
|
|
2055
2042
|
const total = httpSamples.length;
|