-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseNetworkStatus.ts
More file actions
77 lines (66 loc) · 2.5 KB
/
useNetworkStatus.ts
File metadata and controls
77 lines (66 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { useEffect, useRef, useState } from 'react';
import { useStatus } from '@powersync/react';
export type NetworkQuality = 'offline' | 'poor' | 'moderate' | 'good' | 'unknown';
/**
* Ops/sec thresholds that define quality tiers.
* Quality is classified by comparing the measured average ops/sec against
* these boundaries — updated live during a download and preserved after.
*/
export const OPS_PER_SECOND_THRESHOLDS = {
good: 10000, // >= 10000 ops/sec → good
moderate: 5000, // >= 5000 ops/sec → moderate
// anything below moderate → poor
};
function classifyQuality(opsPerSec: number | null, connected: boolean): NetworkQuality {
if (!connected) return 'offline';
if (opsPerSec == null) return 'unknown';
if (opsPerSec >= OPS_PER_SECOND_THRESHOLDS.good) return 'good';
if (opsPerSec >= OPS_PER_SECOND_THRESHOLDS.moderate) return 'moderate';
return 'poor';
}
export interface NetworkStatus {
quality: NetworkQuality;
opsPerSecond: number | null;
connected: boolean;
downloading: boolean;
}
export function useNetworkStatus(): NetworkStatus {
const status = useStatus();
const connected = status.connected;
const downloading = status.dataFlowStatus.downloading ?? false;
const progress = status.downloadProgress;
const downloadedOps = progress?.downloadedOperations ?? 0;
const downloadStartRef = useRef<number | null>(null);
const wasDownloadingRef = useRef(false);
const [opsPerSecond, setOpsPerSecond] = useState<number | null>(null);
useEffect(() => {
// Download just started
if (downloading && !wasDownloadingRef.current) {
downloadStartRef.current = Date.now();
}
// Update live ops/sec while downloading
if (downloading && downloadStartRef.current != null && downloadedOps > 0) {
const durationSec = (Date.now() - downloadStartRef.current) / 1000;
if (durationSec > 0) {
setOpsPerSecond(Math.round(downloadedOps / durationSec));
}
}
// Download just finished — compute final average
if (!downloading && wasDownloadingRef.current) {
const start = downloadStartRef.current;
if (start != null && downloadedOps > 0) {
const durationSec = (Date.now() - start) / 1000;
if (durationSec > 0) {
setOpsPerSecond(Math.round(downloadedOps / durationSec));
}
}
}
wasDownloadingRef.current = downloading;
}, [downloading, downloadedOps]);
return {
quality: classifyQuality(opsPerSecond, connected),
opsPerSecond,
connected,
downloading
};
}