rn-network-quality 0.1.0
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/LICENSE +20 -0
- package/README.md +899 -0
- package/android/build.gradle +60 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/rnnetworkquality/CellularInfo.kt +34 -0
- package/android/src/main/java/com/rnnetworkquality/DownloadPolicy.kt +26 -0
- package/android/src/main/java/com/rnnetworkquality/Mappers.kt +106 -0
- package/android/src/main/java/com/rnnetworkquality/NetworkMonitor.kt +263 -0
- package/android/src/main/java/com/rnnetworkquality/NetworkProbe.kt +668 -0
- package/android/src/main/java/com/rnnetworkquality/NetworkQualityModule.kt +287 -0
- package/android/src/main/java/com/rnnetworkquality/NetworkQualityPackage.kt +25 -0
- package/android/src/main/java/com/rnnetworkquality/NetworkSnapshot.kt +83 -0
- package/android/src/main/java/com/rnnetworkquality/SnapshotBuilder.kt +92 -0
- package/android/src/main/java/com/rnnetworkquality/Throttler.kt +100 -0
- package/ios/CellularInfo.swift +47 -0
- package/ios/NetworkProbe.swift +391 -0
- package/ios/NetworkQuality.h +8 -0
- package/ios/NetworkQuality.mm +88 -0
- package/ios/NetworkQualityImpl.swift +371 -0
- package/ios/PathSnapshot.swift +109 -0
- package/ios/PrivacyInfo.xcprivacy +23 -0
- package/ios/Throttler.swift +174 -0
- package/lib/module/NativeNetworkQuality.js +5 -0
- package/lib/module/NativeNetworkQuality.js.map +1 -0
- package/lib/module/classify.js +126 -0
- package/lib/module/classify.js.map +1 -0
- package/lib/module/constants.js +52 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/errors.js +18 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/hooks.js +78 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/manager.js +595 -0
- package/lib/module/manager.js.map +1 -0
- package/lib/module/normalize.js +35 -0
- package/lib/module/normalize.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeNetworkQuality.d.ts +50 -0
- package/lib/typescript/src/NativeNetworkQuality.d.ts.map +1 -0
- package/lib/typescript/src/classify.d.ts +12 -0
- package/lib/typescript/src/classify.d.ts.map +1 -0
- package/lib/typescript/src/constants.d.ts +15 -0
- package/lib/typescript/src/constants.d.ts.map +1 -0
- package/lib/typescript/src/errors.d.ts +13 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/hooks.d.ts +18 -0
- package/lib/typescript/src/hooks.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/manager.d.ts +98 -0
- package/lib/typescript/src/manager.d.ts.map +1 -0
- package/lib/typescript/src/normalize.d.ts +5 -0
- package/lib/typescript/src/normalize.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +171 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/mock.js +318 -0
- package/package.json +161 -0
- package/rn-network-quality.podspec +32 -0
- package/src/NativeNetworkQuality.ts +58 -0
- package/src/classify.ts +208 -0
- package/src/constants.ts +48 -0
- package/src/errors.ts +23 -0
- package/src/hooks.ts +110 -0
- package/src/index.tsx +25 -0
- package/src/manager.ts +891 -0
- package/src/normalize.ts +81 -0
- package/src/types.ts +207 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { AppState } from 'react-native';
|
|
4
|
+
import NativeNetworkQuality from "./NativeNetworkQuality.js";
|
|
5
|
+
import { classifyNetworkQuality } from "./classify.js";
|
|
6
|
+
import { DEFAULT_CONFIG } from "./constants.js";
|
|
7
|
+
import { NetworkQualityError } from "./errors.js";
|
|
8
|
+
import { normalizeSnapshot } from "./normalize.js";
|
|
9
|
+
const MIN_AUTO_PROBE_INTERVAL_MS = 15_000;
|
|
10
|
+
const TRANSPORT_CHANGE_DEBOUNCE_MS = 2_000;
|
|
11
|
+
const MAX_LATENCY_SAMPLES = 100;
|
|
12
|
+
const MAX_NATIVE_TIMEOUT_MS = 2_147_483_647;
|
|
13
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
14
|
+
const SUPPORTED_ERROR_CODES = new Set(['E_UNSUPPORTED', 'E_OFFLINE', 'E_INVALID_URL', 'E_PROBE_TIMEOUT', 'E_PROBE_FAILED', 'E_PROBE_SKIPPED']);
|
|
15
|
+
|
|
16
|
+
/** Minimal native surface consumed by the TypeScript manager. */
|
|
17
|
+
|
|
18
|
+
/** Minimal AppState surface consumed by the TypeScript manager. */
|
|
19
|
+
|
|
20
|
+
function cloneProbeConfig(config) {
|
|
21
|
+
return {
|
|
22
|
+
...config
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function cloneConfig(config) {
|
|
26
|
+
return {
|
|
27
|
+
...config,
|
|
28
|
+
thresholds: {
|
|
29
|
+
excellent: {
|
|
30
|
+
...config.thresholds.excellent
|
|
31
|
+
},
|
|
32
|
+
good: {
|
|
33
|
+
...config.thresholds.good
|
|
34
|
+
},
|
|
35
|
+
moderate: {
|
|
36
|
+
...config.thresholds.moderate
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
probe: cloneProbeConfig(config.probe),
|
|
40
|
+
autoProbe: {
|
|
41
|
+
...config.autoProbe
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function mergeConfig(current, patch) {
|
|
46
|
+
const valueOrCurrent = (value, currentValue) => value === undefined ? currentValue : value;
|
|
47
|
+
return {
|
|
48
|
+
throttleMs: valueOrCurrent(patch.throttleMs, current.throttleMs),
|
|
49
|
+
bandwidthChangeThresholdPct: valueOrCurrent(patch.bandwidthChangeThresholdPct, current.bandwidthChangeThresholdPct),
|
|
50
|
+
validationGraceMs: valueOrCurrent(patch.validationGraceMs, current.validationGraceMs),
|
|
51
|
+
thresholds: {
|
|
52
|
+
excellent: {
|
|
53
|
+
minDownlinkKbps: valueOrCurrent(patch.thresholds?.excellent?.minDownlinkKbps, current.thresholds.excellent.minDownlinkKbps),
|
|
54
|
+
maxRttMs: valueOrCurrent(patch.thresholds?.excellent?.maxRttMs, current.thresholds.excellent.maxRttMs)
|
|
55
|
+
},
|
|
56
|
+
good: {
|
|
57
|
+
minDownlinkKbps: valueOrCurrent(patch.thresholds?.good?.minDownlinkKbps, current.thresholds.good.minDownlinkKbps),
|
|
58
|
+
maxRttMs: valueOrCurrent(patch.thresholds?.good?.maxRttMs, current.thresholds.good.maxRttMs)
|
|
59
|
+
},
|
|
60
|
+
moderate: {
|
|
61
|
+
minDownlinkKbps: valueOrCurrent(patch.thresholds?.moderate?.minDownlinkKbps, current.thresholds.moderate.minDownlinkKbps),
|
|
62
|
+
maxRttMs: valueOrCurrent(patch.thresholds?.moderate?.maxRttMs, current.thresholds.moderate.maxRttMs)
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
probe: {
|
|
66
|
+
latencyUrl: valueOrCurrent(patch.probe?.latencyUrl, current.probe.latencyUrl),
|
|
67
|
+
downloadUrl: valueOrCurrent(patch.probe?.downloadUrl, current.probe.downloadUrl),
|
|
68
|
+
latencySamples: valueOrCurrent(patch.probe?.latencySamples, current.probe.latencySamples),
|
|
69
|
+
timeoutMs: valueOrCurrent(patch.probe?.timeoutMs, current.probe.timeoutMs),
|
|
70
|
+
downloadMaxDurationMs: valueOrCurrent(patch.probe?.downloadMaxDurationMs, current.probe.downloadMaxDurationMs),
|
|
71
|
+
downloadMaxBytes: valueOrCurrent(patch.probe?.downloadMaxBytes, current.probe.downloadMaxBytes),
|
|
72
|
+
resultTtlMs: valueOrCurrent(patch.probe?.resultTtlMs, current.probe.resultTtlMs)
|
|
73
|
+
},
|
|
74
|
+
autoProbe: {
|
|
75
|
+
enabled: valueOrCurrent(patch.autoProbe?.enabled, current.autoProbe.enabled),
|
|
76
|
+
intervalMs: valueOrCurrent(patch.autoProbe?.intervalMs, current.autoProbe.intervalMs),
|
|
77
|
+
onTransportChange: valueOrCurrent(patch.autoProbe?.onTransportChange, current.autoProbe.onTransportChange),
|
|
78
|
+
allowOnExpensive: valueOrCurrent(patch.autoProbe?.allowOnExpensive, current.autoProbe.allowOnExpensive),
|
|
79
|
+
allowOnConstrained: valueOrCurrent(patch.autoProbe?.allowOnConstrained, current.autoProbe.allowOnConstrained)
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function assertFiniteNumber(value, path, minimum, exclusiveMinimum = false) {
|
|
84
|
+
const belowMinimum = exclusiveMinimum ? value <= minimum : value < minimum;
|
|
85
|
+
if (!Number.isFinite(value) || belowMinimum) {
|
|
86
|
+
const operator = exclusiveMinimum ? 'greater than' : 'at least';
|
|
87
|
+
throw new TypeError(`${path} must be a finite number ${operator} ${minimum}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function validateProbeConfig(config) {
|
|
91
|
+
if (typeof config.latencyUrl !== 'string' || config.latencyUrl.length === 0) {
|
|
92
|
+
throw new TypeError('probe.latencyUrl must be a non-empty string');
|
|
93
|
+
}
|
|
94
|
+
if (config.downloadUrl !== null && (typeof config.downloadUrl !== 'string' || config.downloadUrl.length === 0)) {
|
|
95
|
+
throw new TypeError('probe.downloadUrl must be null or a non-empty string');
|
|
96
|
+
}
|
|
97
|
+
if (!Number.isInteger(config.latencySamples) || config.latencySamples < 1 || config.latencySamples > MAX_LATENCY_SAMPLES) {
|
|
98
|
+
throw new TypeError(`probe.latencySamples must be an integer between 1 and ${MAX_LATENCY_SAMPLES}`);
|
|
99
|
+
}
|
|
100
|
+
assertFiniteNumber(config.timeoutMs, 'probe.timeoutMs', 0, true);
|
|
101
|
+
if (config.timeoutMs > MAX_NATIVE_TIMEOUT_MS) {
|
|
102
|
+
throw new TypeError(`probe.timeoutMs must be at most ${MAX_NATIVE_TIMEOUT_MS}`);
|
|
103
|
+
}
|
|
104
|
+
assertFiniteNumber(config.downloadMaxDurationMs, 'probe.downloadMaxDurationMs', 0, true);
|
|
105
|
+
if (config.downloadMaxDurationMs > MAX_NATIVE_TIMEOUT_MS) {
|
|
106
|
+
throw new TypeError(`probe.downloadMaxDurationMs must be at most ${MAX_NATIVE_TIMEOUT_MS}`);
|
|
107
|
+
}
|
|
108
|
+
if (!Number.isInteger(config.downloadMaxBytes) || config.downloadMaxBytes <= 0 || config.downloadMaxBytes > MAX_NATIVE_TIMEOUT_MS) {
|
|
109
|
+
throw new TypeError(`probe.downloadMaxBytes must be an integer between 1 and ${MAX_NATIVE_TIMEOUT_MS}`);
|
|
110
|
+
}
|
|
111
|
+
assertFiniteNumber(config.resultTtlMs, 'probe.resultTtlMs', 0);
|
|
112
|
+
}
|
|
113
|
+
function validateConfig(config) {
|
|
114
|
+
assertFiniteNumber(config.throttleMs, 'throttleMs', 0);
|
|
115
|
+
assertFiniteNumber(config.bandwidthChangeThresholdPct, 'bandwidthChangeThresholdPct', 0);
|
|
116
|
+
assertFiniteNumber(config.validationGraceMs, 'validationGraceMs', 0);
|
|
117
|
+
if (config.validationGraceMs > MAX_TIMER_DELAY_MS) {
|
|
118
|
+
throw new TypeError(`validationGraceMs must be at most ${MAX_TIMER_DELAY_MS}`);
|
|
119
|
+
}
|
|
120
|
+
const {
|
|
121
|
+
excellent,
|
|
122
|
+
good,
|
|
123
|
+
moderate
|
|
124
|
+
} = config.thresholds;
|
|
125
|
+
for (const [name, threshold] of Object.entries(config.thresholds)) {
|
|
126
|
+
assertFiniteNumber(threshold.minDownlinkKbps, `thresholds.${name}.minDownlinkKbps`, 0);
|
|
127
|
+
assertFiniteNumber(threshold.maxRttMs, `thresholds.${name}.maxRttMs`, 0);
|
|
128
|
+
}
|
|
129
|
+
if (excellent.minDownlinkKbps < good.minDownlinkKbps || good.minDownlinkKbps < moderate.minDownlinkKbps || excellent.maxRttMs > good.maxRttMs || good.maxRttMs > moderate.maxRttMs) {
|
|
130
|
+
throw new TypeError('thresholds must be monotonic from excellent to good to moderate');
|
|
131
|
+
}
|
|
132
|
+
validateProbeConfig(config.probe);
|
|
133
|
+
assertFiniteNumber(config.autoProbe.intervalMs, 'autoProbe.intervalMs', 0);
|
|
134
|
+
for (const [name, value] of Object.entries(config.autoProbe)) {
|
|
135
|
+
if (name !== 'intervalMs' && typeof value !== 'boolean') {
|
|
136
|
+
throw new TypeError(`autoProbe.${name} must be a boolean`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
...config,
|
|
141
|
+
autoProbe: {
|
|
142
|
+
...config.autoProbe,
|
|
143
|
+
intervalMs: Math.max(MIN_AUTO_PROBE_INTERVAL_MS, config.autoProbe.intervalMs)
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function stateEqualsIgnoringSnapshotTimestamp(first, second) {
|
|
148
|
+
return JSON.stringify({
|
|
149
|
+
...first,
|
|
150
|
+
timestamp: 0
|
|
151
|
+
}) === JSON.stringify({
|
|
152
|
+
...second,
|
|
153
|
+
timestamp: 0
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function errorMessage(error) {
|
|
157
|
+
if (typeof error === 'object' && error !== null && typeof error.message === 'string') {
|
|
158
|
+
return error.message;
|
|
159
|
+
}
|
|
160
|
+
return typeof error === 'string' ? error : 'The network probe failed';
|
|
161
|
+
}
|
|
162
|
+
function wrapProbeError(error) {
|
|
163
|
+
if (error instanceof NetworkQualityError) return error;
|
|
164
|
+
const candidate = typeof error === 'object' && error !== null ? error.code : undefined;
|
|
165
|
+
const code = typeof candidate === 'string' && SUPPORTED_ERROR_CODES.has(candidate) ? candidate : 'E_PROBE_FAILED';
|
|
166
|
+
return new NetworkQualityError(code, errorMessage(error), {
|
|
167
|
+
cause: error
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function unsupportedError() {
|
|
171
|
+
return new NetworkQualityError('E_UNSUPPORTED', 'rn-network-quality is unavailable. Run pod install on iOS, enable the React Native New Architecture, and rebuild the app. Expo Go is not supported; use an Expo development build.');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Coordinates the native module, cached state, listeners, and auto-probes. */
|
|
175
|
+
export class NetworkQualityManager {
|
|
176
|
+
config = cloneConfig(DEFAULT_CONFIG);
|
|
177
|
+
listeners = new Set();
|
|
178
|
+
nativeSubscription = null;
|
|
179
|
+
appStateSubscription = null;
|
|
180
|
+
latestSnapshot = null;
|
|
181
|
+
cachedState = null;
|
|
182
|
+
lastProbe = null;
|
|
183
|
+
lastProbeFailure = null;
|
|
184
|
+
lastProbeResultTtlMs = null;
|
|
185
|
+
lastProbeFailureTtlMs = null;
|
|
186
|
+
networkChangedAt = null;
|
|
187
|
+
inFlightProbe = null;
|
|
188
|
+
probeExpiry = null;
|
|
189
|
+
validationGraceExpiry = null;
|
|
190
|
+
autoProbeInterval = null;
|
|
191
|
+
transportDebounce = null;
|
|
192
|
+
monitoringStopVersion = 0;
|
|
193
|
+
stateVersion = 0;
|
|
194
|
+
constructor(nativeModule = NativeNetworkQuality ?? null, appStateApi = AppState) {
|
|
195
|
+
this.nativeModule = nativeModule;
|
|
196
|
+
this.appStateApi = appStateApi;
|
|
197
|
+
this.appStateStatus = appStateApi.currentState;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Returns whether the native TurboModule is linked and available. */
|
|
201
|
+
isSupported() {
|
|
202
|
+
return this.nativeModule !== null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Deep-merges and validates runtime monitoring and probe configuration. */
|
|
206
|
+
configure(patch) {
|
|
207
|
+
const nativeModule = this.requireNativeModule();
|
|
208
|
+
const nextConfig = validateConfig(mergeConfig(this.config, patch));
|
|
209
|
+
this.config = cloneConfig(nextConfig);
|
|
210
|
+
this.reclassifyCachedSnapshot();
|
|
211
|
+
this.scheduleValidationGraceExpiry();
|
|
212
|
+
if (this.listeners.size > 0) {
|
|
213
|
+
this.refreshAutoProbeLifecycle();
|
|
214
|
+
nativeModule.startMonitoring(this.nativeMonitorOptions());
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Returns a defensive copy of the active runtime configuration. */
|
|
219
|
+
getConfig() {
|
|
220
|
+
this.requireNativeModule();
|
|
221
|
+
return cloneConfig(this.config);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** Fetches, normalizes, classifies, and caches the current native snapshot. */
|
|
225
|
+
getNetworkQuality() {
|
|
226
|
+
const nativeModule = this.requireNativeModule();
|
|
227
|
+
return nativeModule.getCurrentState().then(snapshot => this.acceptNativeSnapshot(snapshot));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Adds a live-state listener and starts native monitoring when necessary. */
|
|
231
|
+
addNetworkQualityListener(listener) {
|
|
232
|
+
const nativeModule = this.requireNativeModule();
|
|
233
|
+
if (this.listeners.size === 0) this.reclassifyCachedSnapshot();
|
|
234
|
+
const record = {
|
|
235
|
+
active: true,
|
|
236
|
+
listener
|
|
237
|
+
};
|
|
238
|
+
const hadCachedState = this.cachedState !== null;
|
|
239
|
+
const versionAtSubscription = this.stateVersion;
|
|
240
|
+
this.listeners.add(record);
|
|
241
|
+
if (this.listeners.size === 1) {
|
|
242
|
+
try {
|
|
243
|
+
this.nativeSubscription = nativeModule.onNetworkStateChange(snapshot => {
|
|
244
|
+
this.acceptNativeSnapshot(snapshot);
|
|
245
|
+
});
|
|
246
|
+
this.scheduleProbeExpiry();
|
|
247
|
+
this.scheduleValidationGraceExpiry();
|
|
248
|
+
this.refreshAutoProbeLifecycle();
|
|
249
|
+
nativeModule.startMonitoring(this.nativeMonitorOptions());
|
|
250
|
+
} catch (error) {
|
|
251
|
+
this.nativeSubscription?.remove();
|
|
252
|
+
this.nativeSubscription = null;
|
|
253
|
+
this.listeners.delete(record);
|
|
254
|
+
this.clearProbeExpiry();
|
|
255
|
+
this.clearValidationGraceExpiry();
|
|
256
|
+
this.stopAutoProbeLifecycle();
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (hadCachedState) {
|
|
261
|
+
queueMicrotask(() => {
|
|
262
|
+
if (record.active && this.cachedState !== null && this.stateVersion === versionAtSubscription) {
|
|
263
|
+
record.listener(this.cachedState);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
remove: () => {
|
|
269
|
+
if (!record.active) return;
|
|
270
|
+
record.active = false;
|
|
271
|
+
this.listeners.delete(record);
|
|
272
|
+
if (this.listeners.size === 0) {
|
|
273
|
+
this.nativeSubscription?.remove();
|
|
274
|
+
this.nativeSubscription = null;
|
|
275
|
+
this.clearProbeExpiry();
|
|
276
|
+
this.clearValidationGraceExpiry();
|
|
277
|
+
this.stopAutoProbeLifecycle();
|
|
278
|
+
this.monitoringStopVersion += 1;
|
|
279
|
+
nativeModule.stopMonitoring();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** Runs one active probe, de-duplicating concurrent calls. */
|
|
286
|
+
probeNetwork(options = {}) {
|
|
287
|
+
const nativeModule = this.requireNativeModule();
|
|
288
|
+
if (this.inFlightProbe !== null) return this.inFlightProbe;
|
|
289
|
+
const probeConfig = {
|
|
290
|
+
...this.config.probe,
|
|
291
|
+
...options
|
|
292
|
+
};
|
|
293
|
+
validateProbeConfig(probeConfig);
|
|
294
|
+
const nativeOptions = {
|
|
295
|
+
latencyUrl: probeConfig.latencyUrl,
|
|
296
|
+
downloadUrl: probeConfig.downloadUrl,
|
|
297
|
+
latencySamples: probeConfig.latencySamples,
|
|
298
|
+
timeoutMs: probeConfig.timeoutMs,
|
|
299
|
+
downloadMaxDurationMs: probeConfig.downloadMaxDurationMs,
|
|
300
|
+
downloadMaxBytes: probeConfig.downloadMaxBytes
|
|
301
|
+
};
|
|
302
|
+
const stopVersionAtStart = this.monitoringStopVersion;
|
|
303
|
+
let transport = 'unknown';
|
|
304
|
+
let nativeProbe;
|
|
305
|
+
try {
|
|
306
|
+
if (this.latestSnapshot !== null) {
|
|
307
|
+
transport = this.latestSnapshot.transport;
|
|
308
|
+
nativeProbe = nativeModule.probe(nativeOptions);
|
|
309
|
+
} else {
|
|
310
|
+
nativeProbe = nativeModule.getCurrentState().then(snapshot => {
|
|
311
|
+
if (this.monitoringStopVersion !== stopVersionAtStart) {
|
|
312
|
+
throw new NetworkQualityError('E_PROBE_FAILED', 'The network probe was cancelled because monitoring stopped.');
|
|
313
|
+
}
|
|
314
|
+
transport = this.acceptNativeSnapshot(snapshot).transport;
|
|
315
|
+
return nativeModule.probe(nativeOptions);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
} catch (error) {
|
|
319
|
+
const wrapped = wrapProbeError(error);
|
|
320
|
+
this.recordProbeFailure(wrapped, transport, probeConfig.resultTtlMs);
|
|
321
|
+
throw wrapped;
|
|
322
|
+
}
|
|
323
|
+
let managedProbe;
|
|
324
|
+
managedProbe = nativeProbe.then(result => {
|
|
325
|
+
const probeResult = {
|
|
326
|
+
...result,
|
|
327
|
+
transport
|
|
328
|
+
};
|
|
329
|
+
this.lastProbe = probeResult;
|
|
330
|
+
this.lastProbeFailure = null;
|
|
331
|
+
this.lastProbeFailureTtlMs = null;
|
|
332
|
+
this.lastProbeResultTtlMs = probeConfig.resultTtlMs;
|
|
333
|
+
this.reclassifyCachedSnapshot();
|
|
334
|
+
this.scheduleProbeExpiry();
|
|
335
|
+
return probeResult;
|
|
336
|
+
}).catch(error => {
|
|
337
|
+
const wrapped = wrapProbeError(error);
|
|
338
|
+
this.recordProbeFailure(wrapped, transport, probeConfig.resultTtlMs);
|
|
339
|
+
throw wrapped;
|
|
340
|
+
}).finally(() => {
|
|
341
|
+
if (this.inFlightProbe === managedProbe) this.inFlightProbe = null;
|
|
342
|
+
});
|
|
343
|
+
this.inFlightProbe = managedProbe;
|
|
344
|
+
return managedProbe;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** Returns the most recent successful active-probe result. */
|
|
348
|
+
getLastProbeResult() {
|
|
349
|
+
this.requireNativeModule();
|
|
350
|
+
return this.lastProbe;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Returns the referentially stable state snapshot used by React. */
|
|
354
|
+
getCachedState() {
|
|
355
|
+
return this.cachedState;
|
|
356
|
+
}
|
|
357
|
+
requireNativeModule() {
|
|
358
|
+
if (this.nativeModule === null) throw unsupportedError();
|
|
359
|
+
return this.nativeModule;
|
|
360
|
+
}
|
|
361
|
+
nativeMonitorOptions() {
|
|
362
|
+
return {
|
|
363
|
+
throttleMs: this.config.throttleMs,
|
|
364
|
+
bandwidthChangeThresholdPct: this.config.bandwidthChangeThresholdPct
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
acceptNativeSnapshot(nativeSnapshot) {
|
|
368
|
+
const snapshot = normalizeSnapshot(nativeSnapshot);
|
|
369
|
+
const previousSnapshot = this.latestSnapshot;
|
|
370
|
+
const previousTransport = previousSnapshot?.transport;
|
|
371
|
+
const networkChanged = previousSnapshot === null || previousSnapshot.isConnected !== snapshot.isConnected || previousSnapshot.transport !== snapshot.transport;
|
|
372
|
+
const transportChanged = previousSnapshot !== null && previousSnapshot.transport !== snapshot.transport;
|
|
373
|
+
if (networkChanged) this.networkChangedAt = Date.now();
|
|
374
|
+
if (transportChanged) {
|
|
375
|
+
this.lastProbeFailure = null;
|
|
376
|
+
this.lastProbeFailureTtlMs = null;
|
|
377
|
+
}
|
|
378
|
+
this.latestSnapshot = snapshot;
|
|
379
|
+
const state = this.buildState(snapshot);
|
|
380
|
+
const acceptedState = this.acceptState(state);
|
|
381
|
+
this.scheduleProbeExpiry();
|
|
382
|
+
this.scheduleValidationGraceExpiry();
|
|
383
|
+
if (previousTransport !== undefined && previousTransport !== snapshot.transport) {
|
|
384
|
+
this.scheduleTransportChangeProbe();
|
|
385
|
+
}
|
|
386
|
+
return acceptedState;
|
|
387
|
+
}
|
|
388
|
+
buildState(snapshot) {
|
|
389
|
+
const classifierConfig = this.lastProbeResultTtlMs === null ? this.config : {
|
|
390
|
+
...this.config,
|
|
391
|
+
probe: {
|
|
392
|
+
...this.config.probe,
|
|
393
|
+
resultTtlMs: this.lastProbeResultTtlMs
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
return {
|
|
397
|
+
...snapshot,
|
|
398
|
+
...classifyNetworkQuality(snapshot, this.lastProbe, classifierConfig, Date.now(), {
|
|
399
|
+
lastProbeFailure: this.lastProbeFailure,
|
|
400
|
+
networkChangedAt: this.networkChangedAt,
|
|
401
|
+
probeResultTtlMs: this.lastProbeResultTtlMs ?? undefined,
|
|
402
|
+
probeFailureTtlMs: this.lastProbeFailureTtlMs ?? undefined
|
|
403
|
+
}),
|
|
404
|
+
lastProbe: this.lastProbe,
|
|
405
|
+
lastProbeFailure: this.lastProbeFailure
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
acceptState(state) {
|
|
409
|
+
if (this.cachedState !== null && stateEqualsIgnoringSnapshotTimestamp(this.cachedState, state)) {
|
|
410
|
+
return this.cachedState;
|
|
411
|
+
}
|
|
412
|
+
this.cachedState = state;
|
|
413
|
+
this.stateVersion += 1;
|
|
414
|
+
for (const record of [...this.listeners]) {
|
|
415
|
+
if (record.active) record.listener(state);
|
|
416
|
+
}
|
|
417
|
+
return state;
|
|
418
|
+
}
|
|
419
|
+
reclassifyCachedSnapshot() {
|
|
420
|
+
if (this.latestSnapshot !== null) {
|
|
421
|
+
this.acceptState(this.buildState(this.latestSnapshot));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
scheduleProbeExpiry() {
|
|
425
|
+
this.clearProbeExpiry();
|
|
426
|
+
const snapshot = this.latestSnapshot;
|
|
427
|
+
if (this.listeners.size === 0 || snapshot === null) return;
|
|
428
|
+
const expirations = [];
|
|
429
|
+
if (this.lastProbe !== null && this.lastProbeResultTtlMs !== null && this.lastProbe.transport === snapshot.transport) {
|
|
430
|
+
expirations.push(this.lastProbe.timestamp + this.lastProbeResultTtlMs + 1);
|
|
431
|
+
}
|
|
432
|
+
if (this.lastProbeFailure !== null && this.lastProbeFailureTtlMs !== null && this.lastProbeFailure.transport === snapshot.transport) {
|
|
433
|
+
expirations.push(this.lastProbeFailure.timestamp + this.lastProbeFailureTtlMs + 1);
|
|
434
|
+
}
|
|
435
|
+
const now = Date.now();
|
|
436
|
+
const futureExpirations = expirations.filter(expiration => expiration > now);
|
|
437
|
+
if (futureExpirations.length === 0) return;
|
|
438
|
+
const remainingMs = Math.min(...futureExpirations) - now;
|
|
439
|
+
const delayMs = Math.min(remainingMs, MAX_TIMER_DELAY_MS);
|
|
440
|
+
this.probeExpiry = setTimeout(() => {
|
|
441
|
+
this.probeExpiry = null;
|
|
442
|
+
this.reclassifyCachedSnapshot();
|
|
443
|
+
this.scheduleProbeExpiry();
|
|
444
|
+
}, delayMs);
|
|
445
|
+
}
|
|
446
|
+
clearProbeExpiry() {
|
|
447
|
+
if (this.probeExpiry !== null) {
|
|
448
|
+
clearTimeout(this.probeExpiry);
|
|
449
|
+
this.probeExpiry = null;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
scheduleValidationGraceExpiry() {
|
|
453
|
+
this.clearValidationGraceExpiry();
|
|
454
|
+
const snapshot = this.latestSnapshot;
|
|
455
|
+
const networkChangedAt = this.networkChangedAt;
|
|
456
|
+
if (snapshot === null || networkChangedAt === null || !snapshot.isConnected || snapshot.isValidated !== false || snapshot.isCaptivePortal === true) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const remainingMs = networkChangedAt + this.config.validationGraceMs - Date.now();
|
|
460
|
+
if (remainingMs <= 0) return;
|
|
461
|
+
this.validationGraceExpiry = setTimeout(() => {
|
|
462
|
+
this.validationGraceExpiry = null;
|
|
463
|
+
this.reclassifyCachedSnapshot();
|
|
464
|
+
}, Math.min(remainingMs, MAX_TIMER_DELAY_MS));
|
|
465
|
+
}
|
|
466
|
+
clearValidationGraceExpiry() {
|
|
467
|
+
if (this.validationGraceExpiry !== null) {
|
|
468
|
+
clearTimeout(this.validationGraceExpiry);
|
|
469
|
+
this.validationGraceExpiry = null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
recordProbeFailure(error, transport, resultTtlMs) {
|
|
473
|
+
if (error.code !== 'E_PROBE_FAILED' && error.code !== 'E_PROBE_TIMEOUT') {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
this.lastProbeFailure = {
|
|
477
|
+
code: error.code,
|
|
478
|
+
message: error.message,
|
|
479
|
+
transport,
|
|
480
|
+
timestamp: Date.now()
|
|
481
|
+
};
|
|
482
|
+
this.lastProbeFailureTtlMs = resultTtlMs;
|
|
483
|
+
this.reclassifyCachedSnapshot();
|
|
484
|
+
this.scheduleProbeExpiry();
|
|
485
|
+
}
|
|
486
|
+
refreshAutoProbeLifecycle() {
|
|
487
|
+
this.stopAutoProbeLifecycle();
|
|
488
|
+
if (!this.config.autoProbe.enabled || this.listeners.size === 0) return;
|
|
489
|
+
this.appStateStatus = this.appStateApi.currentState;
|
|
490
|
+
this.appStateSubscription = this.appStateApi.addEventListener('change', state => {
|
|
491
|
+
this.appStateStatus = state;
|
|
492
|
+
this.clearAutoProbeInterval();
|
|
493
|
+
if (state !== 'active') {
|
|
494
|
+
this.clearTransportDebounce();
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
this.startAutoProbeInterval();
|
|
498
|
+
});
|
|
499
|
+
if (this.appStateStatus === 'active') this.startAutoProbeInterval();
|
|
500
|
+
}
|
|
501
|
+
stopAutoProbeLifecycle() {
|
|
502
|
+
this.clearAutoProbeInterval();
|
|
503
|
+
this.clearTransportDebounce();
|
|
504
|
+
this.appStateSubscription?.remove();
|
|
505
|
+
this.appStateSubscription = null;
|
|
506
|
+
}
|
|
507
|
+
startAutoProbeInterval() {
|
|
508
|
+
if (this.autoProbeInterval !== null) return;
|
|
509
|
+
this.autoProbeInterval = setInterval(() => {
|
|
510
|
+
this.runAutoProbe();
|
|
511
|
+
}, this.config.autoProbe.intervalMs);
|
|
512
|
+
}
|
|
513
|
+
clearAutoProbeInterval() {
|
|
514
|
+
if (this.autoProbeInterval !== null) {
|
|
515
|
+
clearInterval(this.autoProbeInterval);
|
|
516
|
+
this.autoProbeInterval = null;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
clearTransportDebounce() {
|
|
520
|
+
if (this.transportDebounce !== null) {
|
|
521
|
+
clearTimeout(this.transportDebounce);
|
|
522
|
+
this.transportDebounce = null;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
scheduleTransportChangeProbe() {
|
|
526
|
+
if (!this.config.autoProbe.enabled || !this.config.autoProbe.onTransportChange || this.listeners.size === 0 || this.appStateStatus !== 'active') {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
this.clearTransportDebounce();
|
|
530
|
+
this.transportDebounce = setTimeout(() => {
|
|
531
|
+
this.transportDebounce = null;
|
|
532
|
+
this.runAutoProbe();
|
|
533
|
+
}, TRANSPORT_CHANGE_DEBOUNCE_MS);
|
|
534
|
+
}
|
|
535
|
+
runAutoProbe() {
|
|
536
|
+
const snapshot = this.latestSnapshot;
|
|
537
|
+
if (!this.config.autoProbe.enabled || this.listeners.size === 0 || this.appStateStatus !== 'active' || snapshot === null || !snapshot.isConnected || snapshot.isExpensive && !this.config.autoProbe.allowOnExpensive || snapshot.isConstrained && !this.config.autoProbe.allowOnConstrained) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
this.probeNetwork().catch(() => {
|
|
542
|
+
// Automatic probes are best-effort and intentionally silent.
|
|
543
|
+
});
|
|
544
|
+
} catch {
|
|
545
|
+
// Synchronous validation/native errors are also silent for auto-probes.
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
const manager = new NetworkQualityManager();
|
|
550
|
+
|
|
551
|
+
/** Internal render-time support assertion used by the React hooks. */
|
|
552
|
+
export function assertNetworkQualitySupported() {
|
|
553
|
+
if (!manager.isSupported()) throw unsupportedError();
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/** Returns whether the native TurboModule is linked and available. */
|
|
557
|
+
export function isSupported() {
|
|
558
|
+
return manager.isSupported();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/** Deep-merges runtime options into the current configuration. */
|
|
562
|
+
export function configure(config) {
|
|
563
|
+
manager.configure(config);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/** Returns a defensive copy of the current configuration. */
|
|
567
|
+
export function getConfig() {
|
|
568
|
+
return manager.getConfig();
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/** Fetches the current network-quality state. */
|
|
572
|
+
export function getNetworkQuality() {
|
|
573
|
+
return manager.getNetworkQuality();
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** Subscribes to live network-quality state changes. */
|
|
577
|
+
export function addNetworkQualityListener(listener) {
|
|
578
|
+
return manager.addNetworkQualityListener(listener);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/** Runs an active latency and optional throughput probe. */
|
|
582
|
+
export function probeNetwork(options) {
|
|
583
|
+
return manager.probeNetwork(options);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/** Returns the most recent successful active-probe result. */
|
|
587
|
+
export function getLastProbeResult() {
|
|
588
|
+
return manager.getLastProbeResult();
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** Internal stable snapshot getter used by `useSyncExternalStore`. */
|
|
592
|
+
export function getCachedNetworkQualityState() {
|
|
593
|
+
return manager.getCachedState();
|
|
594
|
+
}
|
|
595
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["AppState","NativeNetworkQuality","classifyNetworkQuality","DEFAULT_CONFIG","NetworkQualityError","normalizeSnapshot","MIN_AUTO_PROBE_INTERVAL_MS","TRANSPORT_CHANGE_DEBOUNCE_MS","MAX_LATENCY_SAMPLES","MAX_NATIVE_TIMEOUT_MS","MAX_TIMER_DELAY_MS","SUPPORTED_ERROR_CODES","Set","cloneProbeConfig","config","cloneConfig","thresholds","excellent","good","moderate","probe","autoProbe","mergeConfig","current","patch","valueOrCurrent","value","currentValue","undefined","throttleMs","bandwidthChangeThresholdPct","validationGraceMs","minDownlinkKbps","maxRttMs","latencyUrl","downloadUrl","latencySamples","timeoutMs","downloadMaxDurationMs","downloadMaxBytes","resultTtlMs","enabled","intervalMs","onTransportChange","allowOnExpensive","allowOnConstrained","assertFiniteNumber","path","minimum","exclusiveMinimum","belowMinimum","Number","isFinite","operator","TypeError","validateProbeConfig","length","isInteger","validateConfig","name","threshold","Object","entries","Math","max","stateEqualsIgnoringSnapshotTimestamp","first","second","JSON","stringify","timestamp","errorMessage","error","message","wrapProbeError","candidate","code","has","cause","unsupportedError","NetworkQualityManager","listeners","nativeSubscription","appStateSubscription","latestSnapshot","cachedState","lastProbe","lastProbeFailure","lastProbeResultTtlMs","lastProbeFailureTtlMs","networkChangedAt","inFlightProbe","probeExpiry","validationGraceExpiry","autoProbeInterval","transportDebounce","monitoringStopVersion","stateVersion","constructor","nativeModule","appStateApi","appStateStatus","currentState","isSupported","configure","requireNativeModule","nextConfig","reclassifyCachedSnapshot","scheduleValidationGraceExpiry","size","refreshAutoProbeLifecycle","startMonitoring","nativeMonitorOptions","getConfig","getNetworkQuality","getCurrentState","then","snapshot","acceptNativeSnapshot","addNetworkQualityListener","listener","record","active","hadCachedState","versionAtSubscription","add","onNetworkStateChange","scheduleProbeExpiry","remove","delete","clearProbeExpiry","clearValidationGraceExpiry","stopAutoProbeLifecycle","queueMicrotask","stopMonitoring","probeNetwork","options","probeConfig","nativeOptions","stopVersionAtStart","transport","nativeProbe","wrapped","recordProbeFailure","managedProbe","result","probeResult","catch","finally","getLastProbeResult","getCachedState","nativeSnapshot","previousSnapshot","previousTransport","networkChanged","isConnected","transportChanged","Date","now","state","buildState","acceptedState","acceptState","scheduleTransportChangeProbe","classifierConfig","probeResultTtlMs","probeFailureTtlMs","expirations","push","futureExpirations","filter","expiration","remainingMs","min","delayMs","setTimeout","clearTimeout","isValidated","isCaptivePortal","addEventListener","clearAutoProbeInterval","clearTransportDebounce","startAutoProbeInterval","setInterval","runAutoProbe","clearInterval","isExpensive","isConstrained","manager","assertNetworkQualitySupported","getCachedNetworkQualityState"],"sourceRoot":"..\\..\\src","sources":["manager.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const TRANSPORTS = ['wifi', 'cellular', 'ethernet', 'bluetooth', 'vpn', 'other', 'none', 'unknown'];
|
|
4
|
+
const CELLULAR_GENERATIONS = ['2g', '3g', '4g', '5g'];
|
|
5
|
+
const UNSATISFIED_REASONS = ['notAvailable', 'cellularDenied', 'wifiDenied', 'localNetworkDenied', 'vpnInactive', 'unknown'];
|
|
6
|
+
function includes(values, value) {
|
|
7
|
+
return values.some(candidate => candidate === value);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Narrows a native snapshot to the stable public string unions. */
|
|
11
|
+
export function normalizeSnapshot(snapshot) {
|
|
12
|
+
const transport = includes(TRANSPORTS, snapshot.transport) ? snapshot.transport : 'unknown';
|
|
13
|
+
const cellularGeneration = snapshot.cellularGeneration !== null && includes(CELLULAR_GENERATIONS, snapshot.cellularGeneration) ? snapshot.cellularGeneration : null;
|
|
14
|
+
const unsatisfiedReason = snapshot.unsatisfiedReason === null ? null : includes(UNSATISFIED_REASONS, snapshot.unsatisfiedReason) ? snapshot.unsatisfiedReason : 'unknown';
|
|
15
|
+
return {
|
|
16
|
+
isConnected: snapshot.isConnected,
|
|
17
|
+
isValidated: snapshot.isValidated,
|
|
18
|
+
isCaptivePortal: snapshot.isCaptivePortal,
|
|
19
|
+
transport,
|
|
20
|
+
isVpn: snapshot.isVpn,
|
|
21
|
+
isExpensive: snapshot.isExpensive,
|
|
22
|
+
isConstrained: snapshot.isConstrained,
|
|
23
|
+
isRoaming: snapshot.isRoaming,
|
|
24
|
+
downlinkKbps: snapshot.downlinkKbps,
|
|
25
|
+
uplinkKbps: snapshot.uplinkKbps,
|
|
26
|
+
signalStrength: snapshot.signalStrength,
|
|
27
|
+
cellularGeneration,
|
|
28
|
+
supportsIPv4: snapshot.supportsIPv4,
|
|
29
|
+
supportsIPv6: snapshot.supportsIPv6,
|
|
30
|
+
supportsDNS: snapshot.supportsDNS,
|
|
31
|
+
unsatisfiedReason,
|
|
32
|
+
timestamp: snapshot.timestamp
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=normalize.js.map
|