@taphubhq/sdk-core 0.23.2 → 0.23.3
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 +43 -31
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +43 -31
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1636,15 +1636,15 @@ function normaliseMeResponse(body) {
|
|
|
1636
1636
|
};
|
|
1637
1637
|
}
|
|
1638
1638
|
function normaliseCurrencies(body) {
|
|
1639
|
-
if (!Array.isArray(body)) {
|
|
1639
|
+
if (!body || !Array.isArray(body.listEnabledCurrencies)) {
|
|
1640
1640
|
throw new TaphubServerError("Invalid response from server", {
|
|
1641
1641
|
code: "InvalidResponse"
|
|
1642
1642
|
});
|
|
1643
1643
|
}
|
|
1644
|
-
return body.map((entry) => ({
|
|
1644
|
+
return body.listEnabledCurrencies.map((entry) => ({
|
|
1645
1645
|
code: entry.code,
|
|
1646
1646
|
unit: entry.unit,
|
|
1647
|
-
unitSymbol: entry.
|
|
1647
|
+
unitSymbol: entry.unitSymbol
|
|
1648
1648
|
}));
|
|
1649
1649
|
}
|
|
1650
1650
|
function normaliseWalletNode(node) {
|
|
@@ -1700,6 +1700,9 @@ function normaliseUserPnL(node) {
|
|
|
1700
1700
|
// src/modules/user/queries.ts
|
|
1701
1701
|
var ME_QUERY = "query Me { me { id username wallet_address balance is_demo } }";
|
|
1702
1702
|
var MY_WALLETS_QUERY = "query MyWallets { myWallets { id amount currency isEnable } }";
|
|
1703
|
+
var LIST_ENABLED_CURRENCIES_QUERY = `query ListEnabledCurrencies($input: ListEnabledCurrenciesInput!) {
|
|
1704
|
+
listEnabledCurrencies(input: $input) { code unit unitSymbol }
|
|
1705
|
+
}`;
|
|
1703
1706
|
var MY_WALLET_BY_CURRENCY_QUERY = "query MyWalletByCurrency($currency: String!) { myWalletByCurrency(currency: $currency) { id amount currency isEnable } }";
|
|
1704
1707
|
var USER_PNL_QUERY = `query UserPnL($period: String) {
|
|
1705
1708
|
userPnL(period: $period) {
|
|
@@ -1709,12 +1712,10 @@ var USER_PNL_QUERY = `query UserPnL($period: String) {
|
|
|
1709
1712
|
|
|
1710
1713
|
// src/modules/user/index.ts
|
|
1711
1714
|
var UserModule = class {
|
|
1712
|
-
#rest;
|
|
1713
1715
|
#graphql;
|
|
1714
1716
|
#graphqlUser;
|
|
1715
1717
|
#currencies = null;
|
|
1716
1718
|
constructor(deps) {
|
|
1717
|
-
this.#rest = deps.rest;
|
|
1718
1719
|
this.#graphql = deps.graphql;
|
|
1719
1720
|
this.#graphqlUser = deps.graphqlUser;
|
|
1720
1721
|
}
|
|
@@ -1756,7 +1757,10 @@ var UserModule = class {
|
|
|
1756
1757
|
return this.#currencies;
|
|
1757
1758
|
}
|
|
1758
1759
|
async refreshCurrencies() {
|
|
1759
|
-
const body = await this.#
|
|
1760
|
+
const body = await this.#graphqlUser.request(
|
|
1761
|
+
LIST_ENABLED_CURRENCIES_QUERY,
|
|
1762
|
+
{ input: {} }
|
|
1763
|
+
);
|
|
1760
1764
|
const currencies = normaliseCurrencies(body);
|
|
1761
1765
|
this.#currencies = currencies;
|
|
1762
1766
|
return currencies;
|
|
@@ -1932,23 +1936,28 @@ var NetworkQualityMonitor = class {
|
|
|
1932
1936
|
mqttDisconnectedAt = null;
|
|
1933
1937
|
committedNetwork = "good";
|
|
1934
1938
|
committedBackend = "ok";
|
|
1939
|
+
// The last snapshot we emitted, used to decide whether the next recompute is
|
|
1940
|
+
// worth emitting. Seeded with the initial default so the first real change
|
|
1941
|
+
// (e.g. first backend5xx, first ping) emits against the true starting state.
|
|
1942
|
+
lastEmitted;
|
|
1935
1943
|
tickHandle = null;
|
|
1936
1944
|
onlineListener = null;
|
|
1937
1945
|
offlineListener = null;
|
|
1938
1946
|
disposed = false;
|
|
1939
1947
|
constructor(opts) {
|
|
1940
1948
|
this.bus = opts.bus;
|
|
1949
|
+
this.lastEmitted = this.snapshot();
|
|
1941
1950
|
this.attachBrowserListeners();
|
|
1942
1951
|
this.startTick();
|
|
1943
1952
|
}
|
|
1944
|
-
addSample(sample
|
|
1953
|
+
addSample(sample) {
|
|
1945
1954
|
if (this.disposed) return;
|
|
1946
1955
|
const bucket = this.buckets[sample.source];
|
|
1947
1956
|
bucket.push(sample);
|
|
1948
1957
|
if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
|
|
1949
1958
|
bucket.shift();
|
|
1950
1959
|
}
|
|
1951
|
-
this.recompute(
|
|
1960
|
+
this.recompute();
|
|
1952
1961
|
}
|
|
1953
1962
|
seedFromConnection(seed) {
|
|
1954
1963
|
const rtt = this.resolveSeedRtt(seed);
|
|
@@ -1961,24 +1970,19 @@ var NetworkQualityMonitor = class {
|
|
|
1961
1970
|
});
|
|
1962
1971
|
}
|
|
1963
1972
|
notifyMqttConnect(rttMs) {
|
|
1964
|
-
const prevMqttConnected = this.mqttConnected;
|
|
1965
1973
|
this.mqttConnected = true;
|
|
1966
1974
|
this.mqttDisconnectedAt = null;
|
|
1967
|
-
this.addSample(
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
},
|
|
1974
|
-
prevMqttConnected
|
|
1975
|
-
);
|
|
1975
|
+
this.addSample({
|
|
1976
|
+
ts: this.now(),
|
|
1977
|
+
rtt: rttMs,
|
|
1978
|
+
source: "mqtt",
|
|
1979
|
+
reason: "connect"
|
|
1980
|
+
});
|
|
1976
1981
|
}
|
|
1977
1982
|
notifyMqttDisconnect() {
|
|
1978
|
-
const prevMqttConnected = this.mqttConnected;
|
|
1979
1983
|
this.mqttConnected = false;
|
|
1980
1984
|
this.mqttDisconnectedAt = this.now();
|
|
1981
|
-
this.recompute(
|
|
1985
|
+
this.recompute();
|
|
1982
1986
|
}
|
|
1983
1987
|
notifyMqttPing(rttMs) {
|
|
1984
1988
|
this.smoother.add(rttMs);
|
|
@@ -2002,7 +2006,6 @@ var NetworkQualityMonitor = class {
|
|
|
2002
2006
|
return this.snapshot();
|
|
2003
2007
|
}
|
|
2004
2008
|
reset() {
|
|
2005
|
-
const prev = this.snapshot();
|
|
2006
2009
|
for (const key of Object.keys(this.buckets)) {
|
|
2007
2010
|
this.buckets[key] = [];
|
|
2008
2011
|
}
|
|
@@ -2011,10 +2014,7 @@ var NetworkQualityMonitor = class {
|
|
|
2011
2014
|
this.mqttDisconnectedAt = null;
|
|
2012
2015
|
this.committedNetwork = "good";
|
|
2013
2016
|
this.committedBackend = "ok";
|
|
2014
|
-
|
|
2015
|
-
if (prev.network !== current.network || prev.backend !== current.backend) {
|
|
2016
|
-
this.bus.emit("network:change", { previous: prev, current });
|
|
2017
|
-
}
|
|
2017
|
+
this.emitIfChanged(this.snapshot());
|
|
2018
2018
|
}
|
|
2019
2019
|
tick() {
|
|
2020
2020
|
this.pruneWindow();
|
|
@@ -2069,9 +2069,8 @@ var NetworkQualityMonitor = class {
|
|
|
2069
2069
|
this.buckets[key] = this.buckets[key].filter((s) => s.ts >= cutoff);
|
|
2070
2070
|
}
|
|
2071
2071
|
}
|
|
2072
|
-
recompute(
|
|
2072
|
+
recompute() {
|
|
2073
2073
|
this.pruneWindow();
|
|
2074
|
-
const prev = this.snapshot();
|
|
2075
2074
|
const allSamples = this.allHttpAndMqttSamples();
|
|
2076
2075
|
const realSamples = allSamples.filter((s) => s.source !== "connection");
|
|
2077
2076
|
const useConnection = realSamples.length < COLD_START_REAL_SAMPLE_THRESHOLD;
|
|
@@ -2095,12 +2094,26 @@ var NetworkQualityMonitor = class {
|
|
|
2095
2094
|
this.smoother.releaseOffline();
|
|
2096
2095
|
nextNetwork = this.smoother.level;
|
|
2097
2096
|
}
|
|
2098
|
-
const prevMqttConnected = prevMqttConnectedOverride ?? prev.mqttConnected;
|
|
2099
|
-
const changed = nextNetwork !== this.committedNetwork || backend !== this.committedBackend || this.mqttConnected !== prevMqttConnected;
|
|
2100
2097
|
this.committedNetwork = nextNetwork;
|
|
2101
2098
|
this.committedBackend = backend;
|
|
2099
|
+
this.emitIfChanged(this.snapshot());
|
|
2100
|
+
}
|
|
2101
|
+
// Emits network:change when any *displayed* field of the snapshot moves. This
|
|
2102
|
+
// is compared against the last emitted snapshot (not a snapshot taken at the
|
|
2103
|
+
// top of recompute): notifyMqttPing feeds the smoother BEFORE recompute, so a
|
|
2104
|
+
// same-call snapshot would already carry the new rtt and the change would be
|
|
2105
|
+
// invisible (the original "rtt label freezes on a stable connection" bug).
|
|
2106
|
+
//
|
|
2107
|
+
// Trigger fields: network, backend, mqttConnected, rtt, jitter. rtt/jitter are
|
|
2108
|
+
// bounded by the MQTT ping cadence (~keepalive), so this cannot spam. lossRate
|
|
2109
|
+
// and samplesInWindow are deliberately excluded — they move on every HTTP
|
|
2110
|
+
// sample (request-volume driven) and are diagnostics only; consumers that show
|
|
2111
|
+
// them poll getCurrent().
|
|
2112
|
+
emitIfChanged(current) {
|
|
2113
|
+
const prev = this.lastEmitted;
|
|
2114
|
+
this.lastEmitted = current;
|
|
2115
|
+
const changed = current.network !== prev.network || current.backend !== prev.backend || current.mqttConnected !== prev.mqttConnected || current.rtt !== prev.rtt || current.jitter !== prev.jitter;
|
|
2102
2116
|
if (changed) {
|
|
2103
|
-
const current = this.snapshot();
|
|
2104
2117
|
this.bus.emit("network:change", { previous: prev, current });
|
|
2105
2118
|
}
|
|
2106
2119
|
}
|
|
@@ -2740,7 +2753,6 @@ var TaphubClient = class {
|
|
|
2740
2753
|
onRequest: graphqlProbe
|
|
2741
2754
|
});
|
|
2742
2755
|
this.user = new UserModule({
|
|
2743
|
-
rest: this.#rest,
|
|
2744
2756
|
graphql: this.#graphql,
|
|
2745
2757
|
graphqlUser: this.#graphqlUser
|
|
2746
2758
|
});
|
package/dist/index.d.mts
CHANGED
|
@@ -35,7 +35,7 @@ interface TaphubClientConfig {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
type SignalSource = 'graphql' | 'rest' | 'mqtt' | 'browser' | 'connection';
|
|
38
|
-
type SampleReason = 'ok' | 'network' | 'timeout' | 'offline' | 'backend5xx' | 'backend4xx' | 'gqlError';
|
|
38
|
+
type SampleReason = 'ok' | 'connect' | 'network' | 'timeout' | 'offline' | 'backend5xx' | 'backend4xx' | 'gqlError';
|
|
39
39
|
type Sample = {
|
|
40
40
|
ts: number;
|
|
41
41
|
rtt: number;
|
|
@@ -992,7 +992,6 @@ interface UserPnL {
|
|
|
992
992
|
}
|
|
993
993
|
|
|
994
994
|
interface UserModuleDeps {
|
|
995
|
-
rest: RestTransport;
|
|
996
995
|
graphql: GraphQLTransport;
|
|
997
996
|
graphqlUser: GraphQLTransport;
|
|
998
997
|
}
|
|
@@ -1039,6 +1038,7 @@ declare class NetworkQualityMonitor {
|
|
|
1039
1038
|
private mqttDisconnectedAt;
|
|
1040
1039
|
private committedNetwork;
|
|
1041
1040
|
private committedBackend;
|
|
1041
|
+
private lastEmitted;
|
|
1042
1042
|
private tickHandle;
|
|
1043
1043
|
private onlineListener;
|
|
1044
1044
|
private offlineListener;
|
|
@@ -1046,7 +1046,7 @@ declare class NetworkQualityMonitor {
|
|
|
1046
1046
|
constructor(opts: {
|
|
1047
1047
|
bus: TaphubEventBus<EventMapWithNetwork>;
|
|
1048
1048
|
});
|
|
1049
|
-
addSample(sample: Sample
|
|
1049
|
+
addSample(sample: Sample): void;
|
|
1050
1050
|
seedFromConnection(seed: ConnectionSeed): void;
|
|
1051
1051
|
notifyMqttConnect(rttMs: number): void;
|
|
1052
1052
|
notifyMqttDisconnect(): void;
|
|
@@ -1062,6 +1062,7 @@ declare class NetworkQualityMonitor {
|
|
|
1062
1062
|
private detachBrowserListeners;
|
|
1063
1063
|
private pruneWindow;
|
|
1064
1064
|
private recompute;
|
|
1065
|
+
private emitIfChanged;
|
|
1065
1066
|
private deriveMetricsFrom;
|
|
1066
1067
|
private isHardOffline;
|
|
1067
1068
|
private allHttpAndMqttSamples;
|
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ interface TaphubClientConfig {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
type SignalSource = 'graphql' | 'rest' | 'mqtt' | 'browser' | 'connection';
|
|
38
|
-
type SampleReason = 'ok' | 'network' | 'timeout' | 'offline' | 'backend5xx' | 'backend4xx' | 'gqlError';
|
|
38
|
+
type SampleReason = 'ok' | 'connect' | 'network' | 'timeout' | 'offline' | 'backend5xx' | 'backend4xx' | 'gqlError';
|
|
39
39
|
type Sample = {
|
|
40
40
|
ts: number;
|
|
41
41
|
rtt: number;
|
|
@@ -992,7 +992,6 @@ interface UserPnL {
|
|
|
992
992
|
}
|
|
993
993
|
|
|
994
994
|
interface UserModuleDeps {
|
|
995
|
-
rest: RestTransport;
|
|
996
995
|
graphql: GraphQLTransport;
|
|
997
996
|
graphqlUser: GraphQLTransport;
|
|
998
997
|
}
|
|
@@ -1039,6 +1038,7 @@ declare class NetworkQualityMonitor {
|
|
|
1039
1038
|
private mqttDisconnectedAt;
|
|
1040
1039
|
private committedNetwork;
|
|
1041
1040
|
private committedBackend;
|
|
1041
|
+
private lastEmitted;
|
|
1042
1042
|
private tickHandle;
|
|
1043
1043
|
private onlineListener;
|
|
1044
1044
|
private offlineListener;
|
|
@@ -1046,7 +1046,7 @@ declare class NetworkQualityMonitor {
|
|
|
1046
1046
|
constructor(opts: {
|
|
1047
1047
|
bus: TaphubEventBus<EventMapWithNetwork>;
|
|
1048
1048
|
});
|
|
1049
|
-
addSample(sample: Sample
|
|
1049
|
+
addSample(sample: Sample): void;
|
|
1050
1050
|
seedFromConnection(seed: ConnectionSeed): void;
|
|
1051
1051
|
notifyMqttConnect(rttMs: number): void;
|
|
1052
1052
|
notifyMqttDisconnect(): void;
|
|
@@ -1062,6 +1062,7 @@ declare class NetworkQualityMonitor {
|
|
|
1062
1062
|
private detachBrowserListeners;
|
|
1063
1063
|
private pruneWindow;
|
|
1064
1064
|
private recompute;
|
|
1065
|
+
private emitIfChanged;
|
|
1065
1066
|
private deriveMetricsFrom;
|
|
1066
1067
|
private isHardOffline;
|
|
1067
1068
|
private allHttpAndMqttSamples;
|
package/dist/index.js
CHANGED
|
@@ -1571,15 +1571,15 @@ function normaliseMeResponse(body) {
|
|
|
1571
1571
|
};
|
|
1572
1572
|
}
|
|
1573
1573
|
function normaliseCurrencies(body) {
|
|
1574
|
-
if (!Array.isArray(body)) {
|
|
1574
|
+
if (!body || !Array.isArray(body.listEnabledCurrencies)) {
|
|
1575
1575
|
throw new TaphubServerError("Invalid response from server", {
|
|
1576
1576
|
code: "InvalidResponse"
|
|
1577
1577
|
});
|
|
1578
1578
|
}
|
|
1579
|
-
return body.map((entry) => ({
|
|
1579
|
+
return body.listEnabledCurrencies.map((entry) => ({
|
|
1580
1580
|
code: entry.code,
|
|
1581
1581
|
unit: entry.unit,
|
|
1582
|
-
unitSymbol: entry.
|
|
1582
|
+
unitSymbol: entry.unitSymbol
|
|
1583
1583
|
}));
|
|
1584
1584
|
}
|
|
1585
1585
|
function normaliseWalletNode(node) {
|
|
@@ -1635,6 +1635,9 @@ function normaliseUserPnL(node) {
|
|
|
1635
1635
|
// src/modules/user/queries.ts
|
|
1636
1636
|
var ME_QUERY = "query Me { me { id username wallet_address balance is_demo } }";
|
|
1637
1637
|
var MY_WALLETS_QUERY = "query MyWallets { myWallets { id amount currency isEnable } }";
|
|
1638
|
+
var LIST_ENABLED_CURRENCIES_QUERY = `query ListEnabledCurrencies($input: ListEnabledCurrenciesInput!) {
|
|
1639
|
+
listEnabledCurrencies(input: $input) { code unit unitSymbol }
|
|
1640
|
+
}`;
|
|
1638
1641
|
var MY_WALLET_BY_CURRENCY_QUERY = "query MyWalletByCurrency($currency: String!) { myWalletByCurrency(currency: $currency) { id amount currency isEnable } }";
|
|
1639
1642
|
var USER_PNL_QUERY = `query UserPnL($period: String) {
|
|
1640
1643
|
userPnL(period: $period) {
|
|
@@ -1644,12 +1647,10 @@ var USER_PNL_QUERY = `query UserPnL($period: String) {
|
|
|
1644
1647
|
|
|
1645
1648
|
// src/modules/user/index.ts
|
|
1646
1649
|
var UserModule = class {
|
|
1647
|
-
#rest;
|
|
1648
1650
|
#graphql;
|
|
1649
1651
|
#graphqlUser;
|
|
1650
1652
|
#currencies = null;
|
|
1651
1653
|
constructor(deps) {
|
|
1652
|
-
this.#rest = deps.rest;
|
|
1653
1654
|
this.#graphql = deps.graphql;
|
|
1654
1655
|
this.#graphqlUser = deps.graphqlUser;
|
|
1655
1656
|
}
|
|
@@ -1691,7 +1692,10 @@ var UserModule = class {
|
|
|
1691
1692
|
return this.#currencies;
|
|
1692
1693
|
}
|
|
1693
1694
|
async refreshCurrencies() {
|
|
1694
|
-
const body = await this.#
|
|
1695
|
+
const body = await this.#graphqlUser.request(
|
|
1696
|
+
LIST_ENABLED_CURRENCIES_QUERY,
|
|
1697
|
+
{ input: {} }
|
|
1698
|
+
);
|
|
1695
1699
|
const currencies = normaliseCurrencies(body);
|
|
1696
1700
|
this.#currencies = currencies;
|
|
1697
1701
|
return currencies;
|
|
@@ -1867,23 +1871,28 @@ var NetworkQualityMonitor = class {
|
|
|
1867
1871
|
mqttDisconnectedAt = null;
|
|
1868
1872
|
committedNetwork = "good";
|
|
1869
1873
|
committedBackend = "ok";
|
|
1874
|
+
// The last snapshot we emitted, used to decide whether the next recompute is
|
|
1875
|
+
// worth emitting. Seeded with the initial default so the first real change
|
|
1876
|
+
// (e.g. first backend5xx, first ping) emits against the true starting state.
|
|
1877
|
+
lastEmitted;
|
|
1870
1878
|
tickHandle = null;
|
|
1871
1879
|
onlineListener = null;
|
|
1872
1880
|
offlineListener = null;
|
|
1873
1881
|
disposed = false;
|
|
1874
1882
|
constructor(opts) {
|
|
1875
1883
|
this.bus = opts.bus;
|
|
1884
|
+
this.lastEmitted = this.snapshot();
|
|
1876
1885
|
this.attachBrowserListeners();
|
|
1877
1886
|
this.startTick();
|
|
1878
1887
|
}
|
|
1879
|
-
addSample(sample
|
|
1888
|
+
addSample(sample) {
|
|
1880
1889
|
if (this.disposed) return;
|
|
1881
1890
|
const bucket = this.buckets[sample.source];
|
|
1882
1891
|
bucket.push(sample);
|
|
1883
1892
|
if (bucket.length > WINDOW_MAX_SAMPLES_PER_SOURCE) {
|
|
1884
1893
|
bucket.shift();
|
|
1885
1894
|
}
|
|
1886
|
-
this.recompute(
|
|
1895
|
+
this.recompute();
|
|
1887
1896
|
}
|
|
1888
1897
|
seedFromConnection(seed) {
|
|
1889
1898
|
const rtt = this.resolveSeedRtt(seed);
|
|
@@ -1896,24 +1905,19 @@ var NetworkQualityMonitor = class {
|
|
|
1896
1905
|
});
|
|
1897
1906
|
}
|
|
1898
1907
|
notifyMqttConnect(rttMs) {
|
|
1899
|
-
const prevMqttConnected = this.mqttConnected;
|
|
1900
1908
|
this.mqttConnected = true;
|
|
1901
1909
|
this.mqttDisconnectedAt = null;
|
|
1902
|
-
this.addSample(
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
},
|
|
1909
|
-
prevMqttConnected
|
|
1910
|
-
);
|
|
1910
|
+
this.addSample({
|
|
1911
|
+
ts: this.now(),
|
|
1912
|
+
rtt: rttMs,
|
|
1913
|
+
source: "mqtt",
|
|
1914
|
+
reason: "connect"
|
|
1915
|
+
});
|
|
1911
1916
|
}
|
|
1912
1917
|
notifyMqttDisconnect() {
|
|
1913
|
-
const prevMqttConnected = this.mqttConnected;
|
|
1914
1918
|
this.mqttConnected = false;
|
|
1915
1919
|
this.mqttDisconnectedAt = this.now();
|
|
1916
|
-
this.recompute(
|
|
1920
|
+
this.recompute();
|
|
1917
1921
|
}
|
|
1918
1922
|
notifyMqttPing(rttMs) {
|
|
1919
1923
|
this.smoother.add(rttMs);
|
|
@@ -1937,7 +1941,6 @@ var NetworkQualityMonitor = class {
|
|
|
1937
1941
|
return this.snapshot();
|
|
1938
1942
|
}
|
|
1939
1943
|
reset() {
|
|
1940
|
-
const prev = this.snapshot();
|
|
1941
1944
|
for (const key of Object.keys(this.buckets)) {
|
|
1942
1945
|
this.buckets[key] = [];
|
|
1943
1946
|
}
|
|
@@ -1946,10 +1949,7 @@ var NetworkQualityMonitor = class {
|
|
|
1946
1949
|
this.mqttDisconnectedAt = null;
|
|
1947
1950
|
this.committedNetwork = "good";
|
|
1948
1951
|
this.committedBackend = "ok";
|
|
1949
|
-
|
|
1950
|
-
if (prev.network !== current.network || prev.backend !== current.backend) {
|
|
1951
|
-
this.bus.emit("network:change", { previous: prev, current });
|
|
1952
|
-
}
|
|
1952
|
+
this.emitIfChanged(this.snapshot());
|
|
1953
1953
|
}
|
|
1954
1954
|
tick() {
|
|
1955
1955
|
this.pruneWindow();
|
|
@@ -2004,9 +2004,8 @@ var NetworkQualityMonitor = class {
|
|
|
2004
2004
|
this.buckets[key] = this.buckets[key].filter((s) => s.ts >= cutoff);
|
|
2005
2005
|
}
|
|
2006
2006
|
}
|
|
2007
|
-
recompute(
|
|
2007
|
+
recompute() {
|
|
2008
2008
|
this.pruneWindow();
|
|
2009
|
-
const prev = this.snapshot();
|
|
2010
2009
|
const allSamples = this.allHttpAndMqttSamples();
|
|
2011
2010
|
const realSamples = allSamples.filter((s) => s.source !== "connection");
|
|
2012
2011
|
const useConnection = realSamples.length < COLD_START_REAL_SAMPLE_THRESHOLD;
|
|
@@ -2030,12 +2029,26 @@ var NetworkQualityMonitor = class {
|
|
|
2030
2029
|
this.smoother.releaseOffline();
|
|
2031
2030
|
nextNetwork = this.smoother.level;
|
|
2032
2031
|
}
|
|
2033
|
-
const prevMqttConnected = prevMqttConnectedOverride ?? prev.mqttConnected;
|
|
2034
|
-
const changed = nextNetwork !== this.committedNetwork || backend !== this.committedBackend || this.mqttConnected !== prevMqttConnected;
|
|
2035
2032
|
this.committedNetwork = nextNetwork;
|
|
2036
2033
|
this.committedBackend = backend;
|
|
2034
|
+
this.emitIfChanged(this.snapshot());
|
|
2035
|
+
}
|
|
2036
|
+
// Emits network:change when any *displayed* field of the snapshot moves. This
|
|
2037
|
+
// is compared against the last emitted snapshot (not a snapshot taken at the
|
|
2038
|
+
// top of recompute): notifyMqttPing feeds the smoother BEFORE recompute, so a
|
|
2039
|
+
// same-call snapshot would already carry the new rtt and the change would be
|
|
2040
|
+
// invisible (the original "rtt label freezes on a stable connection" bug).
|
|
2041
|
+
//
|
|
2042
|
+
// Trigger fields: network, backend, mqttConnected, rtt, jitter. rtt/jitter are
|
|
2043
|
+
// bounded by the MQTT ping cadence (~keepalive), so this cannot spam. lossRate
|
|
2044
|
+
// and samplesInWindow are deliberately excluded — they move on every HTTP
|
|
2045
|
+
// sample (request-volume driven) and are diagnostics only; consumers that show
|
|
2046
|
+
// them poll getCurrent().
|
|
2047
|
+
emitIfChanged(current) {
|
|
2048
|
+
const prev = this.lastEmitted;
|
|
2049
|
+
this.lastEmitted = current;
|
|
2050
|
+
const changed = current.network !== prev.network || current.backend !== prev.backend || current.mqttConnected !== prev.mqttConnected || current.rtt !== prev.rtt || current.jitter !== prev.jitter;
|
|
2037
2051
|
if (changed) {
|
|
2038
|
-
const current = this.snapshot();
|
|
2039
2052
|
this.bus.emit("network:change", { previous: prev, current });
|
|
2040
2053
|
}
|
|
2041
2054
|
}
|
|
@@ -2675,7 +2688,6 @@ var TaphubClient = class {
|
|
|
2675
2688
|
onRequest: graphqlProbe
|
|
2676
2689
|
});
|
|
2677
2690
|
this.user = new UserModule({
|
|
2678
|
-
rest: this.#rest,
|
|
2679
2691
|
graphql: this.#graphql,
|
|
2680
2692
|
graphqlUser: this.#graphqlUser
|
|
2681
2693
|
});
|