@akbeniwal/react-native-smart-netinfo 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 akbeniwal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # react-native-smart-netinfo
2
+
3
+ A lightweight, zero-dependency, smart network connection monitor for React Native and React Native Web. It keeps track of device connectivity, measures latency (ping), rates the connection quality, and automatically/manually estimates download speeds in Mbps.
4
+
5
+ ## Features
6
+
7
+ - 🌐 **Online/Offline Detection**: Standard and reliable reachability check.
8
+ - ⚑ **Latency Measuring (Ping)**: Periodic background pinging to verify real internet access.
9
+ - πŸ“Ά **Connection Quality**: Automatically rates network latency as `'poor' | 'good' | 'excellent'`.
10
+ - πŸš€ **Speed Test**: Estimate download throughput speed (in Mbps) by downloading a configurable asset.
11
+ - πŸ”„ **Auto Speed Test**: Automatically run speed test when transitioning from offline to online.
12
+ - πŸ“± **Foreground Check**: Recheck connectivity instantly when the app transitions back to the foreground.
13
+ - πŸ•ΈοΈ **Web Compatibility**: Smooth fallback and support for browser online/offline events (perfect for React Native Web).
14
+ - 🧩 **Zero Native Dependencies**: No need for linking or dealing with native pods. Uses standard `fetch` and `AppState`.
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # Using npm
22
+ npm install react-native-smart-netinfo
23
+
24
+ # Using yarn
25
+ yarn add react-native-smart-netinfo
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Usage
31
+
32
+ ### 1. Basic Event Subscription (TypeScript/JavaScript)
33
+
34
+ Subscribe to network state updates anywhere in your app:
35
+
36
+ ```typescript
37
+ import { SmartNetInfo, NetworkState } from 'react-native-smart-netinfo';
38
+
39
+ // (Optional) Configure settings
40
+ SmartNetInfo.configure({
41
+ pingIntervalMs: 30000, // Ping check every 30 seconds
42
+ timeoutMs: 5000,
43
+ speedTestFileSizeInBytes: 90000,
44
+ disableAutoSpeedTest: false, // Automatically run speed test on online transition
45
+ });
46
+
47
+ // Subscribe to state updates
48
+ const unsubscribe = SmartNetInfo.addEventListener((state: NetworkState) => {
49
+ console.log('Is connected:', state.isConnected);
50
+ console.log('Is internet reachable:', state.isInternetReachable);
51
+ console.log('Latency (ms):', state.latencyMs);
52
+ console.log('Connection Quality:', state.connectionQuality); // 'excellent' | 'good' | 'poor'
53
+ console.log('Internet Speed (Mbps):', state.internetSpeed);
54
+ console.log('Is Speed Testing:', state.isTestingSpeed);
55
+ });
56
+
57
+ // Unsubscribe later to clean up
58
+ unsubscribe();
59
+ ```
60
+
61
+ ---
62
+
63
+ ### 2. React Hook Integration
64
+
65
+ Create a custom hook to use `SmartNetInfo` easily in your React Native components:
66
+
67
+ ```tsx
68
+ import { useEffect, useState } from 'react';
69
+ import { SmartNetInfo, NetworkState } from 'react-native-smart-netinfo';
70
+
71
+ export function useNetworkStatus() {
72
+ const [status, setStatus] = useState<NetworkState>({
73
+ isConnected: null,
74
+ isInternetReachable: null,
75
+ latencyMs: null,
76
+ connectionQuality: null,
77
+ internetSpeed: null,
78
+ isTestingSpeed: false,
79
+ });
80
+
81
+ useEffect(() => {
82
+ const unsubscribe = SmartNetInfo.addEventListener((nextState) => {
83
+ setStatus(nextState);
84
+ });
85
+
86
+ return () => {
87
+ unsubscribe();
88
+ };
89
+ }, []);
90
+
91
+ return {
92
+ ...status,
93
+ runSpeedTest: () => SmartNetInfo.runSpeedTest(),
94
+ };
95
+ }
96
+ ```
97
+
98
+ Then use it inside any component:
99
+
100
+ ```tsx
101
+ import React from 'react';
102
+ import { View, Text, Button, ActivityIndicator } from 'react-native';
103
+ import { useNetworkStatus } from './useNetworkStatus';
104
+
105
+ export default function ConnectionScreen() {
106
+ const {
107
+ isConnected,
108
+ isInternetReachable,
109
+ latencyMs,
110
+ connectionQuality,
111
+ internetSpeed,
112
+ isTestingSpeed,
113
+ runSpeedTest
114
+ } = useNetworkStatus();
115
+
116
+ return (
117
+ <View style={{ padding: 20, alignItems: 'center', justifyContent: 'center', flex: 1 }}>
118
+ <Text style={{ fontSize: 20, fontWeight: 'bold' }}>
119
+ Network: {isConnected ? 'Connected' : 'Disconnected'}
120
+ </Text>
121
+
122
+ <Text>Internet Reachable: {isInternetReachable ? 'Yes' : 'No'}</Text>
123
+ <Text>Latency: {latencyMs ? `${latencyMs}ms` : 'Calculating...'}</Text>
124
+ <Text>Quality: {connectionQuality ? connectionQuality.toUpperCase() : 'Calculating...'}</Text>
125
+ <Text>Speed: {internetSpeed ? `${internetSpeed} Mbps` : 'No speed test run yet'}</Text>
126
+
127
+ {isTestingSpeed ? (
128
+ <ActivityIndicator size="small" color="#0000ff" />
129
+ ) : (
130
+ <Button title="Test Speed Now" onPress={runSpeedTest} disabled={!isInternetReachable} />
131
+ )}
132
+ </View>
133
+ );
134
+ }
135
+ ```
136
+
137
+ ---
138
+
139
+ ## API Reference
140
+
141
+ ### `SmartNetInfo.configure(config: Partial<SmartNetInfoConfig>): void`
142
+ Customizes settings. If the monitor is currently running, configuring settings will restart the monitoring session using the updated configurations.
143
+
144
+ ### `SmartNetInfo.fetch(): Promise<NetworkState>`
145
+ Forces an immediate network latency check and returns the latest `NetworkState`.
146
+
147
+ ### `SmartNetInfo.addEventListener(listener: NetworkStateListener): () => void`
148
+ Subscribes a listener to network changes. Returns an `unsubscribe` function. If monitoring is not active, calling this will automatically start monitoring.
149
+
150
+ ### `SmartNetInfo.removeEventListener(listener: NetworkStateListener): void`
151
+ Manually unsubscribes a listener. If all listeners are removed, it automatically stops background monitoring, cleaning up timers and system hooks.
152
+
153
+ ### `SmartNetInfo.runSpeedTest(): Promise<number | null>`
154
+ Manually initiates a speed test, downloads the speed test asset, updates the state (`internetSpeed` and `isTestingSpeed`), and returns the estimated speed in Mbps.
155
+
156
+ ### `SmartNetInfo.startMonitoring(): void`
157
+ Manually starts monitoring. You normally don't need to call this manually unless you are calling `fetch()` without subscriptions and want background polling active.
158
+
159
+ ### `SmartNetInfo.stopMonitoring(): void`
160
+ Manually stops monitoring, cleaning up timers, AppState listeners, and window listeners.
161
+
162
+ ---
163
+
164
+ ## Types
165
+
166
+ ```typescript
167
+ export type ConnectionQuality = 'poor' | 'good' | 'excellent';
168
+
169
+ export interface NetworkState {
170
+ isConnected: boolean | null;
171
+ isInternetReachable: boolean | null;
172
+ latencyMs: number | null;
173
+ connectionQuality: ConnectionQuality | null;
174
+ internetSpeed: number | null;
175
+ isTestingSpeed: boolean;
176
+ }
177
+
178
+ export interface SmartNetInfoConfig {
179
+ pingIntervalMs?: number; // Background checking frequency in ms (default: 30000)
180
+ timeoutMs?: number; // Request timeout in ms (default: 5000)
181
+ speedTestFileSizeInBytes?: number; // Expected file size (default: 90000)
182
+ disableAutoSpeedTest?: boolean; // If true, only speed test when runSpeedTest() is called (default: false)
183
+ }
184
+ ```
185
+
186
+ ## License
187
+
188
+ MIT Β© akbeniwal
@@ -0,0 +1,56 @@
1
+ import { NetworkState, SmartNetInfoConfig, NetworkStateListener } from './types';
2
+ declare class SmartNetInfoManager {
3
+ private config;
4
+ private state;
5
+ private listeners;
6
+ private intervalId;
7
+ private appStateSubscription;
8
+ private isMonitoring;
9
+ /**
10
+ * Configure the SmartNetInfo options.
11
+ * If already monitoring, it will restart the monitoring process to apply new intervals.
12
+ */
13
+ configure(config: Partial<SmartNetInfoConfig>): void;
14
+ /**
15
+ * Fetches the current network state immediately by performing a connectivity check.
16
+ */
17
+ fetch(): Promise<NetworkState>;
18
+ /**
19
+ * Subscribe to network state changes.
20
+ * Automatically starts monitoring if it was not already running.
21
+ *
22
+ * @param listener Callback function receiving the updated NetworkState
23
+ * @returns A cleanup function to unsubscribe
24
+ */
25
+ addEventListener(listener: NetworkStateListener): () => void;
26
+ /**
27
+ * Unsubscribe a listener from network state changes.
28
+ * Automatically stops monitoring if no listeners remain.
29
+ *
30
+ * @param listener Callback function to unsubscribe
31
+ */
32
+ removeEventListener(listener: NetworkStateListener): void;
33
+ /**
34
+ * Triggers an internet speed test manually.
35
+ *
36
+ * @returns Estimated download speed in Mbps, or null if test fails
37
+ */
38
+ runSpeedTest(): Promise<number | null>;
39
+ /**
40
+ * Start monitoring network status (polling, AppState transitions, and browser online/offline events).
41
+ */
42
+ startMonitoring(): void;
43
+ /**
44
+ * Stop monitoring network status and clean up timers and listeners.
45
+ */
46
+ stopMonitoring(): void;
47
+ private handleAppStateChange;
48
+ private handleWebOnline;
49
+ private handleWebOffline;
50
+ private checkConnectivity;
51
+ private updateState;
52
+ private notifyListeners;
53
+ }
54
+ export declare const SmartNetInfo: SmartNetInfoManager;
55
+ export default SmartNetInfo;
56
+ //# sourceMappingURL=SmartNetInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartNetInfo.d.ts","sourceRoot":"","sources":["../src/SmartNetInfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAQjF,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAKZ;IAEF,OAAO,CAAC,KAAK,CAOX;IAEF,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,YAAY,CAAS;IAE7B;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI;IAQ3D;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC;IAK3C;;;;;;OAMG;IACI,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAanE;;;;;OAKG;IACI,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAOhE;;;;OAIG;IACU,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiBnD;;OAEG;IACI,eAAe,IAAI,IAAI;IAoC9B;;OAEG;IACI,cAAc,IAAI,IAAI;IA0B7B,OAAO,CAAC,oBAAoB,CAI1B;IAEF,OAAO,CAAC,eAAe,CAGrB;IAEF,OAAO,CAAC,gBAAgB,CAOtB;YAEY,iBAAiB;IAuB/B,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,eAAe;CASxB;AAED,eAAO,MAAM,YAAY,qBAA4B,CAAC;AACtD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,208 @@
1
+ import { AppState } from 'react-native';
2
+ import { getConnectionQuality } from './utils/getConnectionQuality';
3
+ import { getLatency } from './utils/getLatency';
4
+ import { runSpeedTest as executeSpeedTest } from './utils/runSpeedTest';
5
+ const PING_URL = 'https://clients3.google.com/generate_204';
6
+ const SPEED_TEST_URL = 'https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js';
7
+ class SmartNetInfoManager {
8
+ constructor() {
9
+ this.config = {
10
+ pingIntervalMs: 30000,
11
+ timeoutMs: 5000,
12
+ speedTestFileSizeInBytes: 90000,
13
+ disableAutoSpeedTest: false,
14
+ };
15
+ this.state = {
16
+ isConnected: null,
17
+ isInternetReachable: null,
18
+ latencyMs: null,
19
+ connectionQuality: null,
20
+ internetSpeed: null,
21
+ isTestingSpeed: false,
22
+ };
23
+ this.listeners = new Set();
24
+ this.intervalId = null;
25
+ this.appStateSubscription = null;
26
+ this.isMonitoring = false;
27
+ this.handleAppStateChange = (nextAppState) => {
28
+ if (nextAppState === 'active') {
29
+ this.checkConnectivity();
30
+ }
31
+ };
32
+ this.handleWebOnline = () => {
33
+ this.updateState({ isConnected: true, isInternetReachable: true });
34
+ this.checkConnectivity();
35
+ };
36
+ this.handleWebOffline = () => {
37
+ this.updateState({
38
+ isConnected: false,
39
+ isInternetReachable: false,
40
+ latencyMs: null,
41
+ connectionQuality: null,
42
+ });
43
+ };
44
+ }
45
+ /**
46
+ * Configure the SmartNetInfo options.
47
+ * If already monitoring, it will restart the monitoring process to apply new intervals.
48
+ */
49
+ configure(config) {
50
+ this.config = { ...this.config, ...config };
51
+ if (this.isMonitoring) {
52
+ this.stopMonitoring();
53
+ this.startMonitoring();
54
+ }
55
+ }
56
+ /**
57
+ * Fetches the current network state immediately by performing a connectivity check.
58
+ */
59
+ async fetch() {
60
+ await this.checkConnectivity();
61
+ return this.state;
62
+ }
63
+ /**
64
+ * Subscribe to network state changes.
65
+ * Automatically starts monitoring if it was not already running.
66
+ *
67
+ * @param listener Callback function receiving the updated NetworkState
68
+ * @returns A cleanup function to unsubscribe
69
+ */
70
+ addEventListener(listener) {
71
+ this.listeners.add(listener);
72
+ // Provide the current state immediately to the new listener
73
+ listener(this.state);
74
+ if (!this.isMonitoring) {
75
+ this.startMonitoring();
76
+ }
77
+ return () => this.removeEventListener(listener);
78
+ }
79
+ /**
80
+ * Unsubscribe a listener from network state changes.
81
+ * Automatically stops monitoring if no listeners remain.
82
+ *
83
+ * @param listener Callback function to unsubscribe
84
+ */
85
+ removeEventListener(listener) {
86
+ this.listeners.delete(listener);
87
+ if (this.listeners.size === 0 && this.isMonitoring) {
88
+ this.stopMonitoring();
89
+ }
90
+ }
91
+ /**
92
+ * Triggers an internet speed test manually.
93
+ *
94
+ * @returns Estimated download speed in Mbps, or null if test fails
95
+ */
96
+ async runSpeedTest() {
97
+ if (this.state.isTestingSpeed) {
98
+ return this.state.internetSpeed;
99
+ }
100
+ this.updateState({ isTestingSpeed: true });
101
+ const speed = await executeSpeedTest(SPEED_TEST_URL, this.config.speedTestFileSizeInBytes);
102
+ this.updateState({
103
+ internetSpeed: speed,
104
+ isTestingSpeed: false,
105
+ });
106
+ return speed;
107
+ }
108
+ /**
109
+ * Start monitoring network status (polling, AppState transitions, and browser online/offline events).
110
+ */
111
+ startMonitoring() {
112
+ if (this.isMonitoring)
113
+ return;
114
+ this.isMonitoring = true;
115
+ // Run initial check immediately
116
+ this.checkConnectivity().then(() => {
117
+ // Auto run speed test on initial connect if online
118
+ if (this.state.isInternetReachable &&
119
+ this.state.internetSpeed === null &&
120
+ !this.config.disableAutoSpeedTest) {
121
+ this.runSpeedTest();
122
+ }
123
+ });
124
+ // Set up periodic polling
125
+ if (this.config.pingIntervalMs > 0) {
126
+ this.intervalId = setInterval(() => this.checkConnectivity(), this.config.pingIntervalMs);
127
+ }
128
+ // React Native AppState listener to detect foreground transitions
129
+ try {
130
+ this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange);
131
+ }
132
+ catch (error) {
133
+ console.warn('SmartNetInfo failed to register AppState listener:', error);
134
+ }
135
+ // Web browser window event listeners for react-native-web compatibility
136
+ const hasWindowListeners = typeof window !== 'undefined' && typeof window.addEventListener === 'function';
137
+ if (hasWindowListeners) {
138
+ window.addEventListener('online', this.handleWebOnline);
139
+ window.addEventListener('offline', this.handleWebOffline);
140
+ }
141
+ }
142
+ /**
143
+ * Stop monitoring network status and clean up timers and listeners.
144
+ */
145
+ stopMonitoring() {
146
+ if (!this.isMonitoring)
147
+ return;
148
+ this.isMonitoring = false;
149
+ if (this.intervalId) {
150
+ clearInterval(this.intervalId);
151
+ this.intervalId = null;
152
+ }
153
+ if (this.appStateSubscription) {
154
+ if (typeof this.appStateSubscription.remove === 'function') {
155
+ this.appStateSubscription.remove();
156
+ }
157
+ else {
158
+ // Fallback for older React Native versions
159
+ AppState.removeEventListener?.('change', this.handleAppStateChange);
160
+ }
161
+ this.appStateSubscription = null;
162
+ }
163
+ const hasWindowListeners = typeof window !== 'undefined' && typeof window.removeEventListener === 'function';
164
+ if (hasWindowListeners) {
165
+ window.removeEventListener('online', this.handleWebOnline);
166
+ window.removeEventListener('offline', this.handleWebOffline);
167
+ }
168
+ }
169
+ async checkConnectivity() {
170
+ const { isReachable, latencyMs } = await getLatency(PING_URL, this.config.timeoutMs);
171
+ const wasInternetReachable = this.state.isInternetReachable;
172
+ this.updateState({
173
+ isConnected: isReachable,
174
+ isInternetReachable: isReachable,
175
+ latencyMs,
176
+ connectionQuality: getConnectionQuality(latencyMs),
177
+ });
178
+ // If internet just became reachable and we haven't run speed test yet, trigger auto speed test
179
+ if (isReachable &&
180
+ wasInternetReachable === false &&
181
+ this.state.internetSpeed === null &&
182
+ !this.config.disableAutoSpeedTest) {
183
+ this.runSpeedTest();
184
+ }
185
+ }
186
+ updateState(partialState) {
187
+ const nextState = { ...this.state, ...partialState };
188
+ // Check if anything actually changed
189
+ const hasChanged = Object.keys(nextState).some((key) => nextState[key] !== this.state[key]);
190
+ if (hasChanged) {
191
+ this.state = nextState;
192
+ this.notifyListeners();
193
+ }
194
+ }
195
+ notifyListeners() {
196
+ this.listeners.forEach((listener) => {
197
+ try {
198
+ listener(this.state);
199
+ }
200
+ catch (error) {
201
+ console.error('Error in SmartNetInfo listener:', error);
202
+ }
203
+ });
204
+ }
205
+ }
206
+ export const SmartNetInfo = new SmartNetInfoManager();
207
+ export default SmartNetInfo;
208
+ //# sourceMappingURL=SmartNetInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartNetInfo.js","sourceRoot":"","sources":["../src/SmartNetInfo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { SmartNetInfo, default } from './SmartNetInfo';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACvD,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { SmartNetInfo, default } from './SmartNetInfo';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACvD,cAAc,SAAS,CAAC"}
@@ -0,0 +1,27 @@
1
+ export type ConnectionQuality = 'poor' | 'good' | 'excellent';
2
+ export interface NetworkState {
3
+ /** True if the network check succeeded, false if it failed or timed out */
4
+ isConnected: boolean | null;
5
+ /** True if internet reachability check succeeded */
6
+ isInternetReachable: boolean | null;
7
+ /** Round-trip ping latency in milliseconds */
8
+ latencyMs: number | null;
9
+ /** Connection quality based on latency ('poor' | 'good' | 'excellent') */
10
+ connectionQuality: ConnectionQuality | null;
11
+ /** Estimated internet download speed in Mbps (automatically measured when online) */
12
+ internetSpeed: number | null;
13
+ /** True if a speed test is currently running */
14
+ isTestingSpeed: boolean;
15
+ }
16
+ export interface SmartNetInfoConfig {
17
+ /** The interval in milliseconds to poll the connection (defaults to 30000ms, set to 0 to disable polling) */
18
+ pingIntervalMs?: number;
19
+ /** The fetch timeout in milliseconds (defaults to 5000ms) */
20
+ timeoutMs?: number;
21
+ /** File size of the speed test URL in bytes (defaults to 90000 bytes for jQuery) */
22
+ speedTestFileSizeInBytes?: number;
23
+ /** If true, disables the automatic speed test on mount/online transitions (defaults to false) */
24
+ disableAutoSpeedTest?: boolean;
25
+ }
26
+ export type NetworkStateListener = (state: NetworkState) => void;
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,oDAAoD;IACpD,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,qFAAqF;IACrF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gDAAgD;IAChD,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,6GAA6G;IAC7G,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,iGAAiG;IACjG,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { ConnectionQuality } from '../types';
2
+ /**
3
+ * Categorizes a round-trip connection latency (in milliseconds) into a descriptive rating.
4
+ *
5
+ * @param latencyMs Latency in milliseconds or null if offline/unknown
6
+ * @returns ConnectionQuality rating or null
7
+ */
8
+ export declare function getConnectionQuality(latencyMs: number | null): ConnectionQuality | null;
9
+ //# sourceMappingURL=getConnectionQuality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getConnectionQuality.d.ts","sourceRoot":"","sources":["../../src/utils/getConnectionQuality.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAWvF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Categorizes a round-trip connection latency (in milliseconds) into a descriptive rating.
3
+ *
4
+ * @param latencyMs Latency in milliseconds or null if offline/unknown
5
+ * @returns ConnectionQuality rating or null
6
+ */
7
+ export function getConnectionQuality(latencyMs) {
8
+ if (latencyMs === null || latencyMs < 0) {
9
+ return null;
10
+ }
11
+ if (latencyMs < 150) {
12
+ return 'excellent';
13
+ }
14
+ if (latencyMs < 400) {
15
+ return 'good';
16
+ }
17
+ return 'poor';
18
+ }
19
+ //# sourceMappingURL=getConnectionQuality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getConnectionQuality.js","sourceRoot":"","sources":["../../src/utils/getConnectionQuality.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAwB;IAC3D,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface LatencyResult {
2
+ /** True if the ping request responded with an HTTP status < 400 */
3
+ isReachable: boolean;
4
+ /** Latency in milliseconds, or null if the check timed out or failed */
5
+ latencyMs: number | null;
6
+ }
7
+ /**
8
+ * Pings a URL (normally with a HEAD request) to verify internet reachability and measure round-trip latency.
9
+ * Uses an AbortController to support timeouts.
10
+ *
11
+ * @param pingUrl The target URL to ping
12
+ * @param timeoutMs Request timeout in milliseconds
13
+ * @returns A promise resolving to LatencyResult
14
+ */
15
+ export declare function getLatency(pingUrl: string, timeoutMs: number): Promise<LatencyResult>;
16
+ //# sourceMappingURL=getLatency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLatency.d.ts","sourceRoot":"","sources":["../../src/utils/getLatency.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,wEAAwE;IACxE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA6B3F"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Pings a URL (normally with a HEAD request) to verify internet reachability and measure round-trip latency.
3
+ * Uses an AbortController to support timeouts.
4
+ *
5
+ * @param pingUrl The target URL to ping
6
+ * @param timeoutMs Request timeout in milliseconds
7
+ * @returns A promise resolving to LatencyResult
8
+ */
9
+ export async function getLatency(pingUrl, timeoutMs) {
10
+ const startTime = Date.now();
11
+ try {
12
+ const controller = new AbortController();
13
+ const timeoutId = setTimeout(() => {
14
+ controller.abort();
15
+ }, timeoutMs);
16
+ // Perform HEAD request to verify connectivity and save bandwidth
17
+ const response = await fetch(pingUrl, {
18
+ method: 'HEAD',
19
+ signal: controller.signal,
20
+ headers: {
21
+ 'Cache-Control': 'no-cache, no-store, must-revalidate',
22
+ 'Pragma': 'no-cache',
23
+ 'Expires': '0',
24
+ },
25
+ });
26
+ clearTimeout(timeoutId);
27
+ const isReachable = response.ok || response.status < 400;
28
+ const latencyMs = Date.now() - startTime;
29
+ return { isReachable, latencyMs };
30
+ }
31
+ catch (error) {
32
+ // If HEAD fails, we could try GET, but usually standard endpoints support HEAD or GET.
33
+ // If it fails due to network/timeout, we are offline.
34
+ return { isReachable: false, latencyMs: null };
35
+ }
36
+ }
37
+ //# sourceMappingURL=getLatency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLatency.js","sourceRoot":"","sources":["../../src/utils/getLatency.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,SAAiB;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,iEAAiE;QACjE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE;gBACP,eAAe,EAAE,qCAAqC;gBACtD,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,GAAG;aACf;SACF,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACzC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uFAAuF;QACvF,sDAAsD;QACtD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Runs a download speed test by fetching a remote asset, reading the response
3
+ * completely, and calculating the throughput speed in Mbps.
4
+ *
5
+ * @param speedTestUrl URL of the remote asset to download
6
+ * @param speedTestFileSizeInBytes Known size of the remote asset in bytes
7
+ * @returns A promise resolving to the estimated download speed in Mbps, or null if the test fails
8
+ */
9
+ export declare function runSpeedTest(speedTestUrl: string, speedTestFileSizeInBytes: number): Promise<number | null>;
10
+ //# sourceMappingURL=runSpeedTest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runSpeedTest.d.ts","sourceRoot":"","sources":["../../src/utils/runSpeedTest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,wBAAwB,EAAE,MAAM,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkCxB"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Runs a download speed test by fetching a remote asset, reading the response
3
+ * completely, and calculating the throughput speed in Mbps.
4
+ *
5
+ * @param speedTestUrl URL of the remote asset to download
6
+ * @param speedTestFileSizeInBytes Known size of the remote asset in bytes
7
+ * @returns A promise resolving to the estimated download speed in Mbps, or null if the test fails
8
+ */
9
+ export async function runSpeedTest(speedTestUrl, speedTestFileSizeInBytes) {
10
+ try {
11
+ const startTime = Date.now();
12
+ const response = await fetch(speedTestUrl, {
13
+ method: 'GET',
14
+ headers: {
15
+ 'Cache-Control': 'no-cache, no-store, must-revalidate',
16
+ 'Pragma': 'no-cache',
17
+ 'Expires': '0',
18
+ },
19
+ });
20
+ if (!response.ok) {
21
+ throw new Error(`Speed test download failed with status: ${response.status}`);
22
+ }
23
+ // Fully consume the response body so that we measure the complete download duration
24
+ await response.text();
25
+ const durationSec = (Date.now() - startTime) / 1000;
26
+ if (durationSec <= 0) {
27
+ return null;
28
+ }
29
+ const fileSizeBits = speedTestFileSizeInBytes * 8;
30
+ const speedMbps = fileSizeBits / durationSec / 1000000;
31
+ // Round to 2 decimal places (e.g. 15.45)
32
+ return Math.round(speedMbps * 100) / 100;
33
+ }
34
+ catch (error) {
35
+ console.warn('Network speed test failed:', error);
36
+ return null;
37
+ }
38
+ }
39
+ //# sourceMappingURL=runSpeedTest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runSpeedTest.js","sourceRoot":"","sources":["../../src/utils/runSpeedTest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAAoB,EACpB,wBAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;YACzC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,eAAe,EAAE,qCAAqC;gBACtD,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,GAAG;aACf;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,oFAAoF;QACpF,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEtB,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;QACpD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAG,wBAAwB,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;QAEvD,yCAAyC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@akbeniwal/react-native-smart-netinfo",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight smart network monitoring library for React Native with internet reachability, latency monitoring, connection quality detection and speed testing.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
12
+ "keywords": [
13
+ "react-native",
14
+ "netinfo",
15
+ "network",
16
+ "internet",
17
+ "connectivity",
18
+ "latency",
19
+ "speed-test",
20
+ "ping",
21
+ "network-monitor",
22
+ "react-native-netinfo",
23
+ "offline",
24
+ "online",
25
+ "internet-speed",
26
+ "smart-netinfo"
27
+ ],
28
+ "author": "Abhishek Beniwal",
29
+ "license": "MIT",
30
+ "homepage": "https://github.com/AKBeniwal1700/react-native-smart-netinfo#readme",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/AKBeniwal1700/react-native-smart-netinfo.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/AKBeniwal1700/react-native-smart-netinfo/issues"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "prepare": "npm run build"
41
+ },
42
+ "peerDependencies": {
43
+ "react": ">=18.0.0",
44
+ "react-native": ">=0.72.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/react": "^19.2.16",
48
+ "react": "^19.2.7",
49
+ "react-native": "^0.85.3",
50
+ "typescript": "^6.0.3"
51
+ },
52
+ "engines": {
53
+ "node": ">=18"
54
+ }
55
+ }