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.
Files changed (72) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +899 -0
  3. package/android/build.gradle +60 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/java/com/rnnetworkquality/CellularInfo.kt +34 -0
  6. package/android/src/main/java/com/rnnetworkquality/DownloadPolicy.kt +26 -0
  7. package/android/src/main/java/com/rnnetworkquality/Mappers.kt +106 -0
  8. package/android/src/main/java/com/rnnetworkquality/NetworkMonitor.kt +263 -0
  9. package/android/src/main/java/com/rnnetworkquality/NetworkProbe.kt +668 -0
  10. package/android/src/main/java/com/rnnetworkquality/NetworkQualityModule.kt +287 -0
  11. package/android/src/main/java/com/rnnetworkquality/NetworkQualityPackage.kt +25 -0
  12. package/android/src/main/java/com/rnnetworkquality/NetworkSnapshot.kt +83 -0
  13. package/android/src/main/java/com/rnnetworkquality/SnapshotBuilder.kt +92 -0
  14. package/android/src/main/java/com/rnnetworkquality/Throttler.kt +100 -0
  15. package/ios/CellularInfo.swift +47 -0
  16. package/ios/NetworkProbe.swift +391 -0
  17. package/ios/NetworkQuality.h +8 -0
  18. package/ios/NetworkQuality.mm +88 -0
  19. package/ios/NetworkQualityImpl.swift +371 -0
  20. package/ios/PathSnapshot.swift +109 -0
  21. package/ios/PrivacyInfo.xcprivacy +23 -0
  22. package/ios/Throttler.swift +174 -0
  23. package/lib/module/NativeNetworkQuality.js +5 -0
  24. package/lib/module/NativeNetworkQuality.js.map +1 -0
  25. package/lib/module/classify.js +126 -0
  26. package/lib/module/classify.js.map +1 -0
  27. package/lib/module/constants.js +52 -0
  28. package/lib/module/constants.js.map +1 -0
  29. package/lib/module/errors.js +18 -0
  30. package/lib/module/errors.js.map +1 -0
  31. package/lib/module/hooks.js +78 -0
  32. package/lib/module/hooks.js.map +1 -0
  33. package/lib/module/index.js +19 -0
  34. package/lib/module/index.js.map +1 -0
  35. package/lib/module/manager.js +595 -0
  36. package/lib/module/manager.js.map +1 -0
  37. package/lib/module/normalize.js +35 -0
  38. package/lib/module/normalize.js.map +1 -0
  39. package/lib/module/package.json +1 -0
  40. package/lib/module/types.js +2 -0
  41. package/lib/module/types.js.map +1 -0
  42. package/lib/typescript/package.json +1 -0
  43. package/lib/typescript/src/NativeNetworkQuality.d.ts +50 -0
  44. package/lib/typescript/src/NativeNetworkQuality.d.ts.map +1 -0
  45. package/lib/typescript/src/classify.d.ts +12 -0
  46. package/lib/typescript/src/classify.d.ts.map +1 -0
  47. package/lib/typescript/src/constants.d.ts +15 -0
  48. package/lib/typescript/src/constants.d.ts.map +1 -0
  49. package/lib/typescript/src/errors.d.ts +13 -0
  50. package/lib/typescript/src/errors.d.ts.map +1 -0
  51. package/lib/typescript/src/hooks.d.ts +18 -0
  52. package/lib/typescript/src/hooks.d.ts.map +1 -0
  53. package/lib/typescript/src/index.d.ts +13 -0
  54. package/lib/typescript/src/index.d.ts.map +1 -0
  55. package/lib/typescript/src/manager.d.ts +98 -0
  56. package/lib/typescript/src/manager.d.ts.map +1 -0
  57. package/lib/typescript/src/normalize.d.ts +5 -0
  58. package/lib/typescript/src/normalize.d.ts.map +1 -0
  59. package/lib/typescript/src/types.d.ts +171 -0
  60. package/lib/typescript/src/types.d.ts.map +1 -0
  61. package/mock.js +318 -0
  62. package/package.json +161 -0
  63. package/rn-network-quality.podspec +32 -0
  64. package/src/NativeNetworkQuality.ts +58 -0
  65. package/src/classify.ts +208 -0
  66. package/src/constants.ts +48 -0
  67. package/src/errors.ts +23 -0
  68. package/src/hooks.ts +110 -0
  69. package/src/index.tsx +25 -0
  70. package/src/manager.ts +891 -0
  71. package/src/normalize.ts +81 -0
  72. package/src/types.ts +207 -0
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ import { DEFAULT_CONFIG, QUALITY_ORDER } from "./constants.js";
4
+ function formatValue(value) {
5
+ return Number.isInteger(value) ? String(value) : value.toFixed(1);
6
+ }
7
+ function downlinkTier(value, thresholds) {
8
+ if (value >= thresholds.excellent.minDownlinkKbps) return 'excellent';
9
+ if (value >= thresholds.good.minDownlinkKbps) return 'good';
10
+ if (value >= thresholds.moderate.minDownlinkKbps) return 'moderate';
11
+ return 'poor';
12
+ }
13
+ function rttTier(value, thresholds) {
14
+ if (value <= thresholds.excellent.maxRttMs) return 'excellent';
15
+ if (value <= thresholds.good.maxRttMs) return 'good';
16
+ if (value <= thresholds.moderate.maxRttMs) return 'moderate';
17
+ return 'poor';
18
+ }
19
+ function worseQuality(first, second) {
20
+ const firstIndex = QUALITY_ORDER.indexOf(first);
21
+ const secondIndex = QUALITY_ORDER.indexOf(second);
22
+ return firstIndex <= secondIndex ? first : second;
23
+ }
24
+ function forcedClassification(quality, reason, qualitySource = 'none') {
25
+ return {
26
+ quality,
27
+ qualitySource,
28
+ effectiveDownlinkKbps: null,
29
+ effectiveRttMs: null,
30
+ reasons: [reason]
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Classifies a snapshot using a fresh active probe, an OS estimate, or a
36
+ * cellular-generation heuristic. The function is pure and deterministic.
37
+ */
38
+ export function classifyNetworkQuality(snapshot, probe, config = DEFAULT_CONFIG, now = Date.now(), context = {}) {
39
+ if (!snapshot.isConnected) {
40
+ return forcedClassification('offline', 'not-connected');
41
+ }
42
+ if (snapshot.isCaptivePortal === true) {
43
+ return forcedClassification('poor', 'captive-portal');
44
+ }
45
+ const failure = context.lastProbeFailure ?? null;
46
+ const failureTtlMs = context.probeFailureTtlMs ?? config.probe.resultTtlMs;
47
+ if (failure !== null && failure.transport === snapshot.transport && now - failure.timestamp <= failureTtlMs && (probe === null || failure.timestamp > probe.timestamp)) {
48
+ return forcedClassification('poor', `probe failed: ${failure.code}`, 'probe');
49
+ }
50
+ if (snapshot.isValidated === false) {
51
+ const networkChangedAt = context.networkChangedAt ?? null;
52
+ const validationGraceMs = config.validationGraceMs ?? DEFAULT_CONFIG.validationGraceMs;
53
+ if (networkChangedAt !== null && now - networkChangedAt < validationGraceMs) {
54
+ return forcedClassification('unknown', 'validating');
55
+ }
56
+ return forcedClassification('poor', 'not-validated');
57
+ }
58
+ const reasons = [];
59
+ let freshProbe = null;
60
+ if (probe !== null) {
61
+ if (probe.transport !== snapshot.transport) {
62
+ reasons.push('probe stale (transport changed)');
63
+ } else if (now - probe.timestamp > (context.probeResultTtlMs ?? config.probe.resultTtlMs)) {
64
+ reasons.push('probe stale (expired)');
65
+ } else {
66
+ freshProbe = probe;
67
+ }
68
+ }
69
+ const usedProbeDownlink = freshProbe?.downlinkKbps != null;
70
+ const usedProbeRtt = freshProbe?.rttMs != null;
71
+ const usedOsDownlink = !usedProbeDownlink && snapshot.downlinkKbps !== null;
72
+ const effectiveDownlinkKbps = freshProbe?.downlinkKbps ?? snapshot.downlinkKbps ?? null;
73
+ const effectiveRttMs = freshProbe?.rttMs ?? null;
74
+ let qualitySource = 'none';
75
+ if (usedProbeDownlink || usedProbeRtt) {
76
+ qualitySource = 'probe';
77
+ } else if (usedOsDownlink) {
78
+ qualitySource = 'os-estimate';
79
+ }
80
+ let quality = null;
81
+ if (effectiveDownlinkKbps !== null) {
82
+ const tier = downlinkTier(effectiveDownlinkKbps, config.thresholds);
83
+ reasons.push(`downlink ${formatValue(effectiveDownlinkKbps)} kbps → ${tier}`);
84
+ quality = tier;
85
+ }
86
+ if (effectiveRttMs !== null) {
87
+ const tier = rttTier(effectiveRttMs, config.thresholds);
88
+ reasons.push(`rtt ${formatValue(effectiveRttMs)} ms → ${tier}`);
89
+ quality = quality === null ? tier : worseQuality(quality, tier);
90
+ }
91
+ if (quality !== null) {
92
+ return {
93
+ quality,
94
+ qualitySource,
95
+ effectiveDownlinkKbps,
96
+ effectiveRttMs,
97
+ reasons
98
+ };
99
+ }
100
+ const heuristicQuality = snapshot.cellularGeneration === '5g' || snapshot.cellularGeneration === '4g' ? 'good' : snapshot.cellularGeneration === '3g' ? 'moderate' : snapshot.cellularGeneration === '2g' ? 'poor' : null;
101
+ if (heuristicQuality !== null) {
102
+ reasons.push(`cellular generation ${snapshot.cellularGeneration} → ${heuristicQuality}`);
103
+ return {
104
+ quality: heuristicQuality,
105
+ qualitySource: 'heuristic',
106
+ effectiveDownlinkKbps: null,
107
+ effectiveRttMs: null,
108
+ reasons
109
+ };
110
+ }
111
+ reasons.push('no quality metrics available');
112
+ return {
113
+ quality: 'unknown',
114
+ qualitySource: 'none',
115
+ effectiveDownlinkKbps: null,
116
+ effectiveRttMs: null,
117
+ reasons
118
+ };
119
+ }
120
+
121
+ /** Returns whether a ranked quality tier meets or exceeds a minimum tier. */
122
+ export function isQualityAtLeast(quality, minimum) {
123
+ if (quality === 'unknown' || minimum === 'unknown') return false;
124
+ return QUALITY_ORDER.indexOf(quality) >= QUALITY_ORDER.indexOf(minimum);
125
+ }
126
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_CONFIG","QUALITY_ORDER","formatValue","value","Number","isInteger","String","toFixed","downlinkTier","thresholds","excellent","minDownlinkKbps","good","moderate","rttTier","maxRttMs","worseQuality","first","second","firstIndex","indexOf","secondIndex","forcedClassification","quality","reason","qualitySource","effectiveDownlinkKbps","effectiveRttMs","reasons","classifyNetworkQuality","snapshot","probe","config","now","Date","context","isConnected","isCaptivePortal","failure","lastProbeFailure","failureTtlMs","probeFailureTtlMs","resultTtlMs","transport","timestamp","code","isValidated","networkChangedAt","validationGraceMs","freshProbe","push","probeResultTtlMs","usedProbeDownlink","downlinkKbps","usedProbeRtt","rttMs","usedOsDownlink","tier","heuristicQuality","cellularGeneration","isQualityAtLeast","minimum"],"sourceRoot":"..\\..\\src","sources":["classify.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ /** Default monitoring, classifier, and probe configuration. */
4
+ export const DEFAULT_CONFIG = {
5
+ throttleMs: 1_000,
6
+ bandwidthChangeThresholdPct: 10,
7
+ validationGraceMs: 10_000,
8
+ thresholds: {
9
+ excellent: {
10
+ minDownlinkKbps: 20_000,
11
+ maxRttMs: 50
12
+ },
13
+ good: {
14
+ minDownlinkKbps: 5_000,
15
+ maxRttMs: 150
16
+ },
17
+ moderate: {
18
+ minDownlinkKbps: 1_000,
19
+ maxRttMs: 400
20
+ }
21
+ },
22
+ probe: {
23
+ latencyUrl: 'https://www.gstatic.com/generate_204',
24
+ downloadUrl: 'https://speed.cloudflare.com/__down?bytes=3000000',
25
+ latencySamples: 3,
26
+ timeoutMs: 8_000,
27
+ downloadMaxDurationMs: 3_000,
28
+ downloadMaxBytes: 3_000_000,
29
+ resultTtlMs: 60_000
30
+ },
31
+ autoProbe: {
32
+ enabled: false,
33
+ intervalMs: 60_000,
34
+ onTransportChange: true,
35
+ allowOnExpensive: false,
36
+ allowOnConstrained: false
37
+ }
38
+ };
39
+
40
+ /** Ranked quality tiers from worst to best. `unknown` is intentionally unranked. */
41
+ export const QUALITY_ORDER = ['offline', 'poor', 'moderate', 'good', 'excellent'];
42
+
43
+ /** Error codes that can be returned by the package. */
44
+ export const ERROR_CODES = {
45
+ unsupported: 'E_UNSUPPORTED',
46
+ offline: 'E_OFFLINE',
47
+ invalidUrl: 'E_INVALID_URL',
48
+ probeTimeout: 'E_PROBE_TIMEOUT',
49
+ probeFailed: 'E_PROBE_FAILED',
50
+ probeSkipped: 'E_PROBE_SKIPPED'
51
+ };
52
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_CONFIG","throttleMs","bandwidthChangeThresholdPct","validationGraceMs","thresholds","excellent","minDownlinkKbps","maxRttMs","good","moderate","probe","latencyUrl","downloadUrl","latencySamples","timeoutMs","downloadMaxDurationMs","downloadMaxBytes","resultTtlMs","autoProbe","enabled","intervalMs","onTransportChange","allowOnExpensive","allowOnConstrained","QUALITY_ORDER","ERROR_CODES","unsupported","offline","invalidUrl","probeTimeout","probeFailed","probeSkipped"],"sourceRoot":"..\\..\\src","sources":["constants.ts"],"mappings":";;AAEA;AACA,OAAO,MAAMA,cAAoC,GAAG;EAClDC,UAAU,EAAE,KAAK;EACjBC,2BAA2B,EAAE,EAAE;EAC/BC,iBAAiB,EAAE,MAAM;EACzBC,UAAU,EAAE;IACVC,SAAS,EAAE;MAAEC,eAAe,EAAE,MAAM;MAAEC,QAAQ,EAAE;IAAG,CAAC;IACpDC,IAAI,EAAE;MAAEF,eAAe,EAAE,KAAK;MAAEC,QAAQ,EAAE;IAAI,CAAC;IAC/CE,QAAQ,EAAE;MAAEH,eAAe,EAAE,KAAK;MAAEC,QAAQ,EAAE;IAAI;EACpD,CAAC;EACDG,KAAK,EAAE;IACLC,UAAU,EAAE,sCAAsC;IAClDC,WAAW,EAAE,mDAAmD;IAChEC,cAAc,EAAE,CAAC;IACjBC,SAAS,EAAE,KAAK;IAChBC,qBAAqB,EAAE,KAAK;IAC5BC,gBAAgB,EAAE,SAAS;IAC3BC,WAAW,EAAE;EACf,CAAC;EACDC,SAAS,EAAE;IACTC,OAAO,EAAE,KAAK;IACdC,UAAU,EAAE,MAAM;IAClBC,iBAAiB,EAAE,IAAI;IACvBC,gBAAgB,EAAE,KAAK;IACvBC,kBAAkB,EAAE;EACtB;AACF,CAAC;;AAED;AACA,OAAO,MAAMC,aAA+B,GAAG,CAC7C,SAAS,EACT,MAAM,EACN,UAAU,EACV,MAAM,EACN,WAAW,CACZ;;AAED;AACA,OAAO,MAAMC,WAAW,GAAG;EACzBC,WAAW,EAAE,eAAe;EAC5BC,OAAO,EAAE,WAAW;EACpBC,UAAU,EAAE,eAAe;EAC3BC,YAAY,EAAE,iBAAiB;EAC/BC,WAAW,EAAE,gBAAgB;EAC7BC,YAAY,EAAE;AAChB,CAAU","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ /** Error raised by monitoring and probing operations. */
4
+ export class NetworkQualityError extends Error {
5
+ /** Stable machine-readable error code. */
6
+
7
+ /** Original platform error, when one is available. */
8
+
9
+ /** Creates a network-quality error with a stable code and helpful message. */
10
+ constructor(code, message, options) {
11
+ super(message);
12
+ this.name = 'NetworkQualityError';
13
+ this.code = code;
14
+ this.cause = options?.cause;
15
+ Object.setPrototypeOf(this, new.target.prototype);
16
+ }
17
+ }
18
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NetworkQualityError","Error","constructor","code","message","options","name","cause","Object","setPrototypeOf","new","target","prototype"],"sourceRoot":"..\\..\\src","sources":["errors.ts"],"mappings":";;AAEA;AACA,OAAO,MAAMA,mBAAmB,SAASC,KAAK,CAAC;EAC7C;;EAGA;;EAGA;EACOC,WAAWA,CAChBC,IAA6B,EAC7BC,OAAe,EACfC,OAA6B,EAC7B;IACA,KAAK,CAACD,OAAO,CAAC;IACd,IAAI,CAACE,IAAI,GAAG,qBAAqB;IACjC,IAAI,CAACH,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACI,KAAK,GAAGF,OAAO,EAAEE,KAAK;IAC3BC,MAAM,CAACC,cAAc,CAAC,IAAI,EAAEC,GAAG,CAACC,MAAM,CAACC,SAAS,CAAC;EACnD;AACF","ignoreList":[]}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
4
+ import { NetworkQualityError } from "./errors.js";
5
+ import { addNetworkQualityListener, assertNetworkQualitySupported, getCachedNetworkQualityState, probeNetwork } from "./manager.js";
6
+ function subscribe(onStoreChange) {
7
+ const subscription = addNetworkQualityListener(() => {
8
+ onStoreChange();
9
+ });
10
+ return () => subscription.remove();
11
+ }
12
+ function getServerSnapshot() {
13
+ return null;
14
+ }
15
+
16
+ /** Subscribes a React component to the referentially stable live state. */
17
+ export function useNetworkQuality() {
18
+ const state = useSyncExternalStore(subscribe, getCachedNetworkQualityState, getServerSnapshot);
19
+ assertNetworkQualitySupported();
20
+ return state;
21
+ }
22
+
23
+ /** State and trigger returned by `useNetworkProbe`. */
24
+
25
+ function asNetworkQualityError(error) {
26
+ return error instanceof NetworkQualityError ? error : new NetworkQualityError('E_PROBE_FAILED', error instanceof Error ? error.message : 'The network probe failed', {
27
+ cause: error
28
+ });
29
+ }
30
+
31
+ /** Provides imperative probing with React-friendly loading and error state. */
32
+ export function useNetworkProbe() {
33
+ const mounted = useRef(true);
34
+ const requestId = useRef(0);
35
+ const [isProbing, setIsProbing] = useState(false);
36
+ const [result, setResult] = useState(null);
37
+ const [error, setError] = useState(null);
38
+ useEffect(() => {
39
+ mounted.current = true;
40
+ return () => {
41
+ mounted.current = false;
42
+ requestId.current += 1;
43
+ };
44
+ }, []);
45
+ const probe = useCallback(async options => {
46
+ const currentRequest = requestId.current + 1;
47
+ requestId.current = currentRequest;
48
+ if (mounted.current) {
49
+ setIsProbing(true);
50
+ setError(null);
51
+ }
52
+ try {
53
+ const nextResult = await probeNetwork(options);
54
+ if (mounted.current && requestId.current === currentRequest) {
55
+ setResult(nextResult);
56
+ }
57
+ return nextResult;
58
+ } catch (caught) {
59
+ const nextError = asNetworkQualityError(caught);
60
+ if (mounted.current && requestId.current === currentRequest) {
61
+ setError(nextError);
62
+ }
63
+ throw nextError;
64
+ } finally {
65
+ if (mounted.current && requestId.current === currentRequest) {
66
+ setIsProbing(false);
67
+ }
68
+ }
69
+ }, []);
70
+ assertNetworkQualitySupported();
71
+ return {
72
+ probe,
73
+ isProbing,
74
+ result,
75
+ error
76
+ };
77
+ }
78
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","useRef","useState","useSyncExternalStore","NetworkQualityError","addNetworkQualityListener","assertNetworkQualitySupported","getCachedNetworkQualityState","probeNetwork","subscribe","onStoreChange","subscription","remove","getServerSnapshot","useNetworkQuality","state","asNetworkQualityError","error","Error","message","cause","useNetworkProbe","mounted","requestId","isProbing","setIsProbing","result","setResult","setError","current","probe","options","currentRequest","nextResult","caught","nextError"],"sourceRoot":"..\\..\\src","sources":["hooks.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ /** Purely classifies a network snapshot and optional active-probe result. */
4
+ export { classifyNetworkQuality, isQualityAtLeast } from "./classify.js";
5
+
6
+ /** Default configuration and ranked quality tiers. */
7
+ export { DEFAULT_CONFIG, QUALITY_ORDER } from "./constants.js";
8
+
9
+ /** Error type used by all package operations. */
10
+ export { NetworkQualityError } from "./errors.js";
11
+
12
+ /** React hooks for live state and on-demand active probes. */
13
+ export { useNetworkProbe, useNetworkQuality } from "./hooks.js";
14
+
15
+ /** Runtime configuration, snapshots, listeners, and active probing. */
16
+ export { addNetworkQualityListener, configure, getConfig, getLastProbeResult, getNetworkQuality, isSupported, probeNetwork } from "./manager.js";
17
+
18
+ /** Public network-quality types. */
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["classifyNetworkQuality","isQualityAtLeast","DEFAULT_CONFIG","QUALITY_ORDER","NetworkQualityError","useNetworkProbe","useNetworkQuality","addNetworkQualityListener","configure","getConfig","getLastProbeResult","getNetworkQuality","isSupported","probeNetwork"],"sourceRoot":"..\\..\\src","sources":["index.tsx"],"mappings":";;AAAA;AACA,SAASA,sBAAsB,EAAEC,gBAAgB,QAAQ,eAAY;;AAErE;AACA,SAASC,cAAc,EAAEC,aAAa,QAAQ,gBAAa;;AAE3D;AACA,SAASC,mBAAmB,QAAQ,aAAU;;AAE9C;AACA,SAASC,eAAe,EAAEC,iBAAiB,QAAQ,YAAS;;AAE5D;AACA,SACEC,yBAAyB,EACzBC,SAAS,EACTC,SAAS,EACTC,kBAAkB,EAClBC,iBAAiB,EACjBC,WAAW,EACXC,YAAY,QACP,cAAW;;AAElB","ignoreList":[]}