1const roundSpeed = (bandwidth) => {
2 return Math.round(bandwidth / 1250) / 100;
3};
4
5const calculateJitter = (latencyMeasurements) => {
6 if (!latencyMeasurements || latencyMeasurements.length < 2) return null;
7 let totalDiff = 0;
8 for (let i = 1; i < latencyMeasurements.length; i++) {
9 totalDiff += Math.abs(latencyMeasurements[i] - latencyMeasurements[i - 1]);
10 }
11 return parseFloat((totalDiff / (latencyMeasurements.length - 1)).toFixed(2));
12};
13
14export const parseOokla = (test) => {
15 let ping = Math.round(test.ping.latency);
16 let jitter = test.ping.jitter ? parseFloat(test.ping.jitter.toFixed(2)) : null;
17 let download = roundSpeed(test.download.bandwidth);
18 let upload = roundSpeed(test.upload.bandwidth);
19 let time = Math.round((test.download.elapsed + test.upload.elapsed) / 1000);
20 let serverName = test.server?.name ?? null;
21 let serverHost = test.server?.host ?? null;
22
23 return {ping, jitter, download, upload, time, resultId: test.result?.id, serverName, serverHost};
24};
25
26export const parseLibre = (test) => ({...test, ping: Math.round(test.ping),
27 jitter: test.jitter ? parseFloat(parseFloat(test.jitter).toFixed(2)) : null,
28 time: Math.round(test.elapsed / 1000), resultId: null,
29 serverName: test.server?.name ?? null, serverHost: test.server?.url ?? null});
30
31export const parseCloudflare = (test) => {
32 if (test && test.latency_measurement && test.speed_measurements) {
33 const downloadTests = test.speed_measurements.filter(t => t.test_type === "Download");
34 const uploadTests = test.speed_measurements.filter(t => t.test_type === "Upload");
35
36 const downloadSpeeds = downloadTests.map(t => t.max || t.median || 0);
37 const download = downloadSpeeds.length > 0 ? Math.max(...downloadSpeeds) : 0;
38
39 const uploadSpeeds = uploadTests.map(t => t.max || t.median || 0);
40 const upload = uploadSpeeds.length > 0 ? Math.max(...uploadSpeeds) : 0;
41
42 const ping = Math.round(test.latency_measurement.avg_latency_ms || 0);
43 const jitter = calculateJitter(test.latency_measurement.latency_measurements);
44
45 const time = Math.round((test.elapsed || 30000) / 1000);
46
47 return {ping, jitter, download: parseFloat(download.toFixed(2)),
48 upload: parseFloat(upload.toFixed(2)), time, resultId: null,
49 serverName: null, serverHost: null};
50 }
51
52 return {ping: 0, jitter: null, download: 0, upload: 0, time: 0, resultId: null,
53 serverName: null, serverHost: null};
54};
55
56export const parseData = (provider, data) => {
57 switch (provider) {
58 case "ookla":
59 return parseOokla(data);
60 case "libre":
61 return parseLibre(data);
62 case "cloudflare":
63 return parseCloudflare(data);
64 default:
65 throw {message: "Invalid provider"};
66 }
67};