@auraqule/react-network-status 0.2.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/README.md +79 -0
- package/dist/index.d.mts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +53 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# react-network-status
|
|
2
|
+
|
|
3
|
+
> A React hook to monitor network connectivity, online/offline state, and connection type. SSR-safe, zero dependencies beyond React.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/react-network-status)
|
|
6
|
+
[](https://bundlephobia.com/package/react-network-status)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install react-network-status
|
|
13
|
+
# or
|
|
14
|
+
pnpm add react-network-status
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { useNetworkStatus } from "react-network-status";
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
const {
|
|
24
|
+
isOnline,
|
|
25
|
+
isOffline,
|
|
26
|
+
connectionType,
|
|
27
|
+
effectiveType,
|
|
28
|
+
downlink,
|
|
29
|
+
rtt,
|
|
30
|
+
saveData,
|
|
31
|
+
refresh,
|
|
32
|
+
} = useNetworkStatus();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
<p>Status: {isOnline ? "Online 🟢" : "Offline 🔴"}</p>
|
|
37
|
+
<p>Connection: {connectionType}</p>
|
|
38
|
+
<p>Effective type: {effectiveType}</p>
|
|
39
|
+
{downlink && <p>Downlink: {downlink} Mbps</p>}
|
|
40
|
+
{rtt && <p>RTT: {rtt} ms</p>}
|
|
41
|
+
{saveData && <p>Data saver: enabled</p>}
|
|
42
|
+
<button onClick={refresh}>Refresh</button>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### `useNetworkStatus()`
|
|
51
|
+
|
|
52
|
+
No options — just call it.
|
|
53
|
+
|
|
54
|
+
### Returns
|
|
55
|
+
|
|
56
|
+
| Value | Type | Description |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `isOnline` | `boolean` | Whether the browser has network access |
|
|
59
|
+
| `isOffline` | `boolean` | Inverse of `isOnline` |
|
|
60
|
+
| `connectionType` | `ConnectionType` | wifi, ethernet, cellular, 2g, 3g, 4g, 5g, unknown |
|
|
61
|
+
| `effectiveType` | `EffectiveConnectionType` | slow-2g, 2g, 3g, 4g, unknown |
|
|
62
|
+
| `downlink` | `number \| undefined` | Estimated bandwidth in Mbps |
|
|
63
|
+
| `rtt` | `number \| undefined` | Estimated round-trip time in ms |
|
|
64
|
+
| `saveData` | `boolean \| undefined` | Whether data saver is enabled |
|
|
65
|
+
| `refresh` | `() => void` | Manually re-read network status |
|
|
66
|
+
|
|
67
|
+
> `connectionType`, `effectiveType`, `downlink`, `rtt`, and `saveData` rely on the [Network Information API](https://developer.mozilla.org/en-US/docs/Web/API/Network_Information_API), which is not supported in all browsers. They will return `undefined` or `"unknown"` when unavailable.
|
|
68
|
+
|
|
69
|
+
## Use Cases
|
|
70
|
+
|
|
71
|
+
- Show offline banners or toasts
|
|
72
|
+
- Disable uploads/fetches when offline
|
|
73
|
+
- Adapt image quality based on connection speed
|
|
74
|
+
- Warn users on slow connections before heavy operations
|
|
75
|
+
- Respect data saver preferences
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type ConnectionType = "wifi" | "ethernet" | "cellular" | "2g" | "3g" | "4g" | "5g" | "slow-2g" | "unknown" | "none";
|
|
2
|
+
type EffectiveConnectionType = "slow-2g" | "2g" | "3g" | "4g" | "unknown";
|
|
3
|
+
interface NetworkStatus {
|
|
4
|
+
/** Whether the browser has network access */
|
|
5
|
+
isOnline: boolean;
|
|
6
|
+
/** Whether the browser is offline */
|
|
7
|
+
isOffline: boolean;
|
|
8
|
+
/** The type of connection (wifi, cellular, etc.) — may be undefined if unsupported */
|
|
9
|
+
connectionType: ConnectionType;
|
|
10
|
+
/** Effective connection type based on observed latency — may be undefined if unsupported */
|
|
11
|
+
effectiveType: EffectiveConnectionType;
|
|
12
|
+
/** Estimated downlink bandwidth in Mbps — undefined if unsupported */
|
|
13
|
+
downlink: number | undefined;
|
|
14
|
+
/** Estimated round-trip time in ms — undefined if unsupported */
|
|
15
|
+
rtt: number | undefined;
|
|
16
|
+
/** Whether the user has enabled data saver mode — undefined if unsupported */
|
|
17
|
+
saveData: boolean | undefined;
|
|
18
|
+
/** Manually re-check network status */
|
|
19
|
+
refresh: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface NetworkInformation extends EventTarget {
|
|
22
|
+
type?: string;
|
|
23
|
+
effectiveType?: string;
|
|
24
|
+
downlink?: number;
|
|
25
|
+
rtt?: number;
|
|
26
|
+
saveData?: boolean;
|
|
27
|
+
addEventListener(type: "change", listener: () => void): void;
|
|
28
|
+
removeEventListener(type: "change", listener: () => void): void;
|
|
29
|
+
}
|
|
30
|
+
declare global {
|
|
31
|
+
interface Navigator {
|
|
32
|
+
connection?: NetworkInformation;
|
|
33
|
+
mozConnection?: NetworkInformation;
|
|
34
|
+
webkitConnection?: NetworkInformation;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
declare function useNetworkStatus(): NetworkStatus;
|
|
38
|
+
|
|
39
|
+
export { type ConnectionType, type EffectiveConnectionType, type NetworkStatus, useNetworkStatus };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type ConnectionType = "wifi" | "ethernet" | "cellular" | "2g" | "3g" | "4g" | "5g" | "slow-2g" | "unknown" | "none";
|
|
2
|
+
type EffectiveConnectionType = "slow-2g" | "2g" | "3g" | "4g" | "unknown";
|
|
3
|
+
interface NetworkStatus {
|
|
4
|
+
/** Whether the browser has network access */
|
|
5
|
+
isOnline: boolean;
|
|
6
|
+
/** Whether the browser is offline */
|
|
7
|
+
isOffline: boolean;
|
|
8
|
+
/** The type of connection (wifi, cellular, etc.) — may be undefined if unsupported */
|
|
9
|
+
connectionType: ConnectionType;
|
|
10
|
+
/** Effective connection type based on observed latency — may be undefined if unsupported */
|
|
11
|
+
effectiveType: EffectiveConnectionType;
|
|
12
|
+
/** Estimated downlink bandwidth in Mbps — undefined if unsupported */
|
|
13
|
+
downlink: number | undefined;
|
|
14
|
+
/** Estimated round-trip time in ms — undefined if unsupported */
|
|
15
|
+
rtt: number | undefined;
|
|
16
|
+
/** Whether the user has enabled data saver mode — undefined if unsupported */
|
|
17
|
+
saveData: boolean | undefined;
|
|
18
|
+
/** Manually re-check network status */
|
|
19
|
+
refresh: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface NetworkInformation extends EventTarget {
|
|
22
|
+
type?: string;
|
|
23
|
+
effectiveType?: string;
|
|
24
|
+
downlink?: number;
|
|
25
|
+
rtt?: number;
|
|
26
|
+
saveData?: boolean;
|
|
27
|
+
addEventListener(type: "change", listener: () => void): void;
|
|
28
|
+
removeEventListener(type: "change", listener: () => void): void;
|
|
29
|
+
}
|
|
30
|
+
declare global {
|
|
31
|
+
interface Navigator {
|
|
32
|
+
connection?: NetworkInformation;
|
|
33
|
+
mozConnection?: NetworkInformation;
|
|
34
|
+
webkitConnection?: NetworkInformation;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
declare function useNetworkStatus(): NetworkStatus;
|
|
38
|
+
|
|
39
|
+
export { type ConnectionType, type EffectiveConnectionType, type NetworkStatus, useNetworkStatus };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
// src/useNetworkStatus.ts
|
|
6
|
+
function getConnection() {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
if (typeof navigator === "undefined") return void 0;
|
|
9
|
+
return (_b = (_a = navigator.connection) != null ? _a : navigator.mozConnection) != null ? _b : navigator.webkitConnection;
|
|
10
|
+
}
|
|
11
|
+
function getConnectionType(connection) {
|
|
12
|
+
var _a;
|
|
13
|
+
if (!(connection == null ? void 0 : connection.type)) return "unknown";
|
|
14
|
+
return (_a = connection.type) != null ? _a : "unknown";
|
|
15
|
+
}
|
|
16
|
+
function getEffectiveType(connection) {
|
|
17
|
+
var _a;
|
|
18
|
+
if (!(connection == null ? void 0 : connection.effectiveType)) return "unknown";
|
|
19
|
+
return (_a = connection.effectiveType) != null ? _a : "unknown";
|
|
20
|
+
}
|
|
21
|
+
function getSnapshot() {
|
|
22
|
+
const isOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
|
|
23
|
+
const connection = getConnection();
|
|
24
|
+
return {
|
|
25
|
+
isOnline,
|
|
26
|
+
isOffline: !isOnline,
|
|
27
|
+
connectionType: getConnectionType(connection),
|
|
28
|
+
effectiveType: getEffectiveType(connection),
|
|
29
|
+
downlink: connection == null ? void 0 : connection.downlink,
|
|
30
|
+
rtt: connection == null ? void 0 : connection.rtt,
|
|
31
|
+
saveData: connection == null ? void 0 : connection.saveData
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function useNetworkStatus() {
|
|
35
|
+
const [status, setStatus] = react.useState(getSnapshot);
|
|
36
|
+
const update = react.useCallback(() => {
|
|
37
|
+
setStatus(getSnapshot());
|
|
38
|
+
}, []);
|
|
39
|
+
react.useEffect(() => {
|
|
40
|
+
window.addEventListener("online", update);
|
|
41
|
+
window.addEventListener("offline", update);
|
|
42
|
+
const connection = getConnection();
|
|
43
|
+
connection == null ? void 0 : connection.addEventListener("change", update);
|
|
44
|
+
return () => {
|
|
45
|
+
window.removeEventListener("online", update);
|
|
46
|
+
window.removeEventListener("offline", update);
|
|
47
|
+
connection == null ? void 0 : connection.removeEventListener("change", update);
|
|
48
|
+
};
|
|
49
|
+
}, [update]);
|
|
50
|
+
return { ...status, refresh: update };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
exports.useNetworkStatus = useNetworkStatus;
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/useNetworkStatus.ts"],"names":["useState","useCallback","useEffect"],"mappings":";;;;;AAsDA,SAAS,aAAA,GAAgD;AAtDzD,EAAA,IAAA,EAAA,EAAA,EAAA;AAuDE,EAAA,IAAI,OAAO,SAAA,KAAc,WAAA,EAAa,OAAO,MAAA;AAC7C,EAAA,OAAA,CACE,qBAAU,UAAA,KAAV,IAAA,GAAA,EAAA,GACA,SAAA,CAAU,aAAA,KADV,YAEA,SAAA,CAAU,gBAAA;AAEd;AAEA,SAAS,kBAAkB,UAAA,EAAiD;AA/D5E,EAAA,IAAA,EAAA;AAgEE,EAAA,IAAI,EAAC,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,IAAA,CAAA,EAAM,OAAO,SAAA;AAC9B,EAAA,OAAA,CAAQ,EAAA,GAAA,UAAA,CAAW,SAAX,IAAA,GAAA,EAAA,GAAsC,SAAA;AAChD;AAEA,SAAS,iBAAiB,UAAA,EAA0D;AApEpF,EAAA,IAAA,EAAA;AAqEE,EAAA,IAAI,EAAC,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,aAAA,CAAA,EAAe,OAAO,SAAA;AACvC,EAAA,OAAA,CAAQ,EAAA,GAAA,UAAA,CAAW,kBAAX,IAAA,GAAA,EAAA,GAAwD,SAAA;AAClE;AAEA,SAAS,WAAA,GAA8C;AACrD,EAAA,MAAM,QAAA,GAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,MAAA,GAAS,IAAA;AACvE,EAAA,MAAM,aAAa,aAAA,EAAc;AAEjC,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,WAAW,CAAC,QAAA;AAAA,IACZ,cAAA,EAAgB,kBAAkB,UAAU,CAAA;AAAA,IAC5C,aAAA,EAAe,iBAAiB,UAAU,CAAA;AAAA,IAC1C,UAAU,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,QAAA;AAAA,IACtB,KAAK,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,GAAA;AAAA,IACjB,UAAU,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY;AAAA,GACxB;AACF;AAEO,SAAS,gBAAA,GAAkC;AAChD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAyC,WAAW,CAAA;AAEhF,EAAA,MAAM,MAAA,GAASC,kBAAY,MAAM;AAC/B,IAAA,SAAA,CAAU,aAAa,CAAA;AAAA,EACzB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,MAAM,CAAA;AACxC,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,MAAM,CAAA;AAEzC,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,iBAAiB,QAAA,EAAU,MAAA,CAAA;AAEvC,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,MAAM,CAAA;AAC3C,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,MAAM,CAAA;AAC5C,MAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,oBAAoB,QAAA,EAAU,MAAA,CAAA;AAAA,IAC5C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAO;AACtC","file":"index.js","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\n\nexport type ConnectionType =\n | \"wifi\"\n | \"ethernet\"\n | \"cellular\"\n | \"2g\"\n | \"3g\"\n | \"4g\"\n | \"5g\"\n | \"slow-2g\"\n | \"unknown\"\n | \"none\";\n\nexport type EffectiveConnectionType = \"slow-2g\" | \"2g\" | \"3g\" | \"4g\" | \"unknown\";\n\nexport interface NetworkStatus {\n /** Whether the browser has network access */\n isOnline: boolean;\n /** Whether the browser is offline */\n isOffline: boolean;\n /** The type of connection (wifi, cellular, etc.) — may be undefined if unsupported */\n connectionType: ConnectionType;\n /** Effective connection type based on observed latency — may be undefined if unsupported */\n effectiveType: EffectiveConnectionType;\n /** Estimated downlink bandwidth in Mbps — undefined if unsupported */\n downlink: number | undefined;\n /** Estimated round-trip time in ms — undefined if unsupported */\n rtt: number | undefined;\n /** Whether the user has enabled data saver mode — undefined if unsupported */\n saveData: boolean | undefined;\n /** Manually re-check network status */\n refresh: () => void;\n}\n\n// Network Information API types (not yet in all TS lib versions)\ninterface NetworkInformation extends EventTarget {\n type?: string;\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n addEventListener(type: \"change\", listener: () => void): void;\n removeEventListener(type: \"change\", listener: () => void): void;\n}\n\ndeclare global {\n interface Navigator {\n connection?: NetworkInformation;\n mozConnection?: NetworkInformation;\n webkitConnection?: NetworkInformation;\n }\n}\n\nfunction getConnection(): NetworkInformation | undefined {\n if (typeof navigator === \"undefined\") return undefined;\n return (\n navigator.connection ??\n navigator.mozConnection ??\n navigator.webkitConnection\n );\n}\n\nfunction getConnectionType(connection?: NetworkInformation): ConnectionType {\n if (!connection?.type) return \"unknown\";\n return (connection.type as ConnectionType) ?? \"unknown\";\n}\n\nfunction getEffectiveType(connection?: NetworkInformation): EffectiveConnectionType {\n if (!connection?.effectiveType) return \"unknown\";\n return (connection.effectiveType as EffectiveConnectionType) ?? \"unknown\";\n}\n\nfunction getSnapshot(): Omit<NetworkStatus, \"refresh\"> {\n const isOnline = typeof navigator !== \"undefined\" ? navigator.onLine : true;\n const connection = getConnection();\n\n return {\n isOnline,\n isOffline: !isOnline,\n connectionType: getConnectionType(connection),\n effectiveType: getEffectiveType(connection),\n downlink: connection?.downlink,\n rtt: connection?.rtt,\n saveData: connection?.saveData,\n };\n}\n\nexport function useNetworkStatus(): NetworkStatus {\n const [status, setStatus] = useState<Omit<NetworkStatus, \"refresh\">>(getSnapshot);\n\n const update = useCallback(() => {\n setStatus(getSnapshot());\n }, []);\n\n useEffect(() => {\n window.addEventListener(\"online\", update);\n window.addEventListener(\"offline\", update);\n\n const connection = getConnection();\n connection?.addEventListener(\"change\", update);\n\n return () => {\n window.removeEventListener(\"online\", update);\n window.removeEventListener(\"offline\", update);\n connection?.removeEventListener(\"change\", update);\n };\n }, [update]);\n\n return { ...status, refresh: update };\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/useNetworkStatus.ts
|
|
4
|
+
function getConnection() {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
if (typeof navigator === "undefined") return void 0;
|
|
7
|
+
return (_b = (_a = navigator.connection) != null ? _a : navigator.mozConnection) != null ? _b : navigator.webkitConnection;
|
|
8
|
+
}
|
|
9
|
+
function getConnectionType(connection) {
|
|
10
|
+
var _a;
|
|
11
|
+
if (!(connection == null ? void 0 : connection.type)) return "unknown";
|
|
12
|
+
return (_a = connection.type) != null ? _a : "unknown";
|
|
13
|
+
}
|
|
14
|
+
function getEffectiveType(connection) {
|
|
15
|
+
var _a;
|
|
16
|
+
if (!(connection == null ? void 0 : connection.effectiveType)) return "unknown";
|
|
17
|
+
return (_a = connection.effectiveType) != null ? _a : "unknown";
|
|
18
|
+
}
|
|
19
|
+
function getSnapshot() {
|
|
20
|
+
const isOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
|
|
21
|
+
const connection = getConnection();
|
|
22
|
+
return {
|
|
23
|
+
isOnline,
|
|
24
|
+
isOffline: !isOnline,
|
|
25
|
+
connectionType: getConnectionType(connection),
|
|
26
|
+
effectiveType: getEffectiveType(connection),
|
|
27
|
+
downlink: connection == null ? void 0 : connection.downlink,
|
|
28
|
+
rtt: connection == null ? void 0 : connection.rtt,
|
|
29
|
+
saveData: connection == null ? void 0 : connection.saveData
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function useNetworkStatus() {
|
|
33
|
+
const [status, setStatus] = useState(getSnapshot);
|
|
34
|
+
const update = useCallback(() => {
|
|
35
|
+
setStatus(getSnapshot());
|
|
36
|
+
}, []);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
window.addEventListener("online", update);
|
|
39
|
+
window.addEventListener("offline", update);
|
|
40
|
+
const connection = getConnection();
|
|
41
|
+
connection == null ? void 0 : connection.addEventListener("change", update);
|
|
42
|
+
return () => {
|
|
43
|
+
window.removeEventListener("online", update);
|
|
44
|
+
window.removeEventListener("offline", update);
|
|
45
|
+
connection == null ? void 0 : connection.removeEventListener("change", update);
|
|
46
|
+
};
|
|
47
|
+
}, [update]);
|
|
48
|
+
return { ...status, refresh: update };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { useNetworkStatus };
|
|
52
|
+
//# sourceMappingURL=index.mjs.map
|
|
53
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/useNetworkStatus.ts"],"names":[],"mappings":";;;AAsDA,SAAS,aAAA,GAAgD;AAtDzD,EAAA,IAAA,EAAA,EAAA,EAAA;AAuDE,EAAA,IAAI,OAAO,SAAA,KAAc,WAAA,EAAa,OAAO,MAAA;AAC7C,EAAA,OAAA,CACE,qBAAU,UAAA,KAAV,IAAA,GAAA,EAAA,GACA,SAAA,CAAU,aAAA,KADV,YAEA,SAAA,CAAU,gBAAA;AAEd;AAEA,SAAS,kBAAkB,UAAA,EAAiD;AA/D5E,EAAA,IAAA,EAAA;AAgEE,EAAA,IAAI,EAAC,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,IAAA,CAAA,EAAM,OAAO,SAAA;AAC9B,EAAA,OAAA,CAAQ,EAAA,GAAA,UAAA,CAAW,SAAX,IAAA,GAAA,EAAA,GAAsC,SAAA;AAChD;AAEA,SAAS,iBAAiB,UAAA,EAA0D;AApEpF,EAAA,IAAA,EAAA;AAqEE,EAAA,IAAI,EAAC,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,aAAA,CAAA,EAAe,OAAO,SAAA;AACvC,EAAA,OAAA,CAAQ,EAAA,GAAA,UAAA,CAAW,kBAAX,IAAA,GAAA,EAAA,GAAwD,SAAA;AAClE;AAEA,SAAS,WAAA,GAA8C;AACrD,EAAA,MAAM,QAAA,GAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,MAAA,GAAS,IAAA;AACvE,EAAA,MAAM,aAAa,aAAA,EAAc;AAEjC,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,WAAW,CAAC,QAAA;AAAA,IACZ,cAAA,EAAgB,kBAAkB,UAAU,CAAA;AAAA,IAC5C,aAAA,EAAe,iBAAiB,UAAU,CAAA;AAAA,IAC1C,UAAU,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,QAAA;AAAA,IACtB,KAAK,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,GAAA;AAAA,IACjB,UAAU,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY;AAAA,GACxB;AACF;AAEO,SAAS,gBAAA,GAAkC;AAChD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAyC,WAAW,CAAA;AAEhF,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,SAAA,CAAU,aAAa,CAAA;AAAA,EACzB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,MAAM,CAAA;AACxC,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,MAAM,CAAA;AAEzC,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,iBAAiB,QAAA,EAAU,MAAA,CAAA;AAEvC,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,MAAM,CAAA;AAC3C,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,MAAM,CAAA;AAC5C,MAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,oBAAoB,QAAA,EAAU,MAAA,CAAA;AAAA,IAC5C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAO;AACtC","file":"index.mjs","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\n\nexport type ConnectionType =\n | \"wifi\"\n | \"ethernet\"\n | \"cellular\"\n | \"2g\"\n | \"3g\"\n | \"4g\"\n | \"5g\"\n | \"slow-2g\"\n | \"unknown\"\n | \"none\";\n\nexport type EffectiveConnectionType = \"slow-2g\" | \"2g\" | \"3g\" | \"4g\" | \"unknown\";\n\nexport interface NetworkStatus {\n /** Whether the browser has network access */\n isOnline: boolean;\n /** Whether the browser is offline */\n isOffline: boolean;\n /** The type of connection (wifi, cellular, etc.) — may be undefined if unsupported */\n connectionType: ConnectionType;\n /** Effective connection type based on observed latency — may be undefined if unsupported */\n effectiveType: EffectiveConnectionType;\n /** Estimated downlink bandwidth in Mbps — undefined if unsupported */\n downlink: number | undefined;\n /** Estimated round-trip time in ms — undefined if unsupported */\n rtt: number | undefined;\n /** Whether the user has enabled data saver mode — undefined if unsupported */\n saveData: boolean | undefined;\n /** Manually re-check network status */\n refresh: () => void;\n}\n\n// Network Information API types (not yet in all TS lib versions)\ninterface NetworkInformation extends EventTarget {\n type?: string;\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n addEventListener(type: \"change\", listener: () => void): void;\n removeEventListener(type: \"change\", listener: () => void): void;\n}\n\ndeclare global {\n interface Navigator {\n connection?: NetworkInformation;\n mozConnection?: NetworkInformation;\n webkitConnection?: NetworkInformation;\n }\n}\n\nfunction getConnection(): NetworkInformation | undefined {\n if (typeof navigator === \"undefined\") return undefined;\n return (\n navigator.connection ??\n navigator.mozConnection ??\n navigator.webkitConnection\n );\n}\n\nfunction getConnectionType(connection?: NetworkInformation): ConnectionType {\n if (!connection?.type) return \"unknown\";\n return (connection.type as ConnectionType) ?? \"unknown\";\n}\n\nfunction getEffectiveType(connection?: NetworkInformation): EffectiveConnectionType {\n if (!connection?.effectiveType) return \"unknown\";\n return (connection.effectiveType as EffectiveConnectionType) ?? \"unknown\";\n}\n\nfunction getSnapshot(): Omit<NetworkStatus, \"refresh\"> {\n const isOnline = typeof navigator !== \"undefined\" ? navigator.onLine : true;\n const connection = getConnection();\n\n return {\n isOnline,\n isOffline: !isOnline,\n connectionType: getConnectionType(connection),\n effectiveType: getEffectiveType(connection),\n downlink: connection?.downlink,\n rtt: connection?.rtt,\n saveData: connection?.saveData,\n };\n}\n\nexport function useNetworkStatus(): NetworkStatus {\n const [status, setStatus] = useState<Omit<NetworkStatus, \"refresh\">>(getSnapshot);\n\n const update = useCallback(() => {\n setStatus(getSnapshot());\n }, []);\n\n useEffect(() => {\n window.addEventListener(\"online\", update);\n window.addEventListener(\"offline\", update);\n\n const connection = getConnection();\n connection?.addEventListener(\"change\", update);\n\n return () => {\n window.removeEventListener(\"online\", update);\n window.removeEventListener(\"offline\", update);\n connection?.removeEventListener(\"change\", update);\n };\n }, [update]);\n\n return { ...status, refresh: update };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@auraqule/react-network-status",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A React hook to monitor network connectivity, online/offline state, and connection type",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"hook",
|
|
8
|
+
"network",
|
|
9
|
+
"online",
|
|
10
|
+
"offline",
|
|
11
|
+
"connectivity",
|
|
12
|
+
"connection"
|
|
13
|
+
],
|
|
14
|
+
"author": "Christian Peters <auraqule@gmail.com>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/auraqule/react-utils-monorepo.git",
|
|
19
|
+
"directory": "packages/react-idle-detect"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./dist/index.mjs",
|
|
27
|
+
"require": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": ">=16.8.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@testing-library/react": "^14.0.0",
|
|
39
|
+
"@types/react": "^18.2.0",
|
|
40
|
+
"react": "^18.3.1",
|
|
41
|
+
"react-dom": "18.3.1",
|
|
42
|
+
"tsup": "^8.0.1",
|
|
43
|
+
"typescript": "^5.3.3",
|
|
44
|
+
"vitest": "^1.2.0"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"dev": "tsup --watch",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"lint": "tsc --noEmit"
|
|
51
|
+
}
|
|
52
|
+
}
|