How tunguyen35/pingvn works
1. What this repo is
- This is a TypeScript/JavaScript measurement library, published as @cloudflare/speedtest.
- The core runtime is browser-side: it measures network quality from a client device against Cloudflare edge endpoints, using browser network timing APIs and WebRTC for packet loss.
2. Primary architecture boundary
- The main boundary is between the public API surface and the measurement engine internals.
- src/index.ts is the library entrypoint; consumers instantiate SpeedTest, configure it, and receive callbacks/results.
- Everything under src/engines, src/Results, src/config, src/utils, and src/logging supports that one public class.
3. Orchestration layer
- The speedtest is driven by a central orchestrator that sequences measurement steps: latency, download, upload, packet loss, and reachability.
- The configured measurement plan is an ordered list, so the system is fundamentally a pipeline of measurement tasks rather than a single monolithic test.
- The engine exposes lifecycle control: start, pause, restart, running state, finish state, and event callbacks.
4. Measurement engines
- src/engines/Latency is implemented through the download API with zero-byte requests and uses request timing to compute RTT-like latency.
- src/engines/BandwidthEngine handles download and upload ramps, including “loaded latency” sampling while transfers are in progress.
- src/engines/PacketLossEngine uses WebRTC/UDP via a TURN server to count lost packets.
- src/engines/ReachabilityEngine appears to be a lighter connectivity check stage.
- The Engine.ts abstraction suggests these are interchangeable measurement units behind a shared contract.
5. Data sources and network dependencies
- Download and upload measurements target Cloudflare HTTP APIs, defaulting to https://speed.cloudflare.com/__down and https://speed.cloudflare.com/__up.
- Latency and bandwidth calculations depend on PerformanceResourceTiming browser data, not just fetch completion time.
- Packet loss is a separate network path using TURN/WebRTC, with credentials optionally fetched from a credentials API or supplied directly.
6. Results pipeline
- src/Results is the post-processing layer that turns raw measurement points into derived metrics.
- It computes reduced values such as unloaded latency, jitter, download/upload bandwidth, packet loss ratio, total duration, and AIM scores.
- The results object is stateful and incremental: it can be queried while a test is still running, but some values are only final after completion.
7. Configuration and thresholds
- src/config centralizes defaults and internal config shape, including request sizes, throttles, duration thresholds, percentiles, and TURN settings.
- src/utils/scaleThreshold.ts and src/utils/numbers.ts indicate the repo relies on numeric reduction/selection logic for percentiles and thresholds.
- Configuration directly affects the measurement strategy, especially the ramp-up behavior for bandwidth and the sample windows for loaded latency.
8. Logging and UI-facing callbacks
- src/logging/logFinalResults.ts suggests the library emits a final structured summary for diagnostics or display.
- The public event model (onResultsChange, onFinish, onError, onRunningChange) is the main interface for integrating with UI or higher-level apps.
- This is an event-driven library, not a request/response API.
9. Browser app and demo surface
- The app/ directory is a browser application wrapper around the library, with index.html, app.js, style.css, manifest.json, sw.js, icons, and Android asset links.
- That makes it a PWA-style demo/host for the speedtest engine, likely the app behind the public Cloudflare speedtest experience.
- app/wrangler.toml indicates deployment as a Cloudflare Worker/Pages-style edge app rather than a traditional server.
10. Example integrations
- example/basic-page is a minimal static usage example.
- example/turn-worker is an integration example for packet-loss support: it provides a Worker-based TURN credential flow for Cloudflare Realtime TURN.
- This example exists because packet-loss measurement is architecturally optional and depends on external infrastructure the consumer must provide.
11. Testing structure
- Unit tests cover config defaults, utility math, result calculations, and URL construction.
- tests/e2e/speedtest.test.ts validates the full measurement flow, which is important because the behavior depends on browser timing APIs and network interactions.
- The test split reflects the repo’s main risk areas: numeric correctness and end-to-end orchestration.
12. Build, packaging, and release concerns
- The package is built from TypeScript and managed as a library, with configs for bundling and linting (tsdown, vitest, ESLint, Prettier).
- GitHub Actions handle build, release PR creation, npm publishing, and Semgrep scanning.
- These workflows don’t change runtime architecture, but they show the repo is designed to ship as a reusable package plus a deployed browser app.
Main entry points: LoadNetworkEngine/index.ts Load Network · src/index.ts SpeedTest · Results.test.ts Unit Tests · MeasurementCalculations.ts Metrics
Components 21
Library
Public package surface and core runtime
- SpeedTest · Library entrypoint and consumer-facing test controller
src/index.ts
Engines
Measurement stages and orchestration
- Engine · Shared abstraction for measurement stages
src/engines/Engine.ts - Latency · Zero-byte request timing used to estimate latency
src/engines/BandwidthEngine/BandwidthEngine.ts - Bandwidth · Ramp-based download and upload measurement with loaded latency sampling
src/engines/BandwidthEngine/BandwidthEngine.ts - Packet Loss · TURN/WebRTC packet-loss measurement over a separate transport
src/engines/PacketLossEngine/PacketLossEngine.ts - Reachability · Lightweight network reachability stage
src/engines/ReachabilityEngine/index.ts - Load Network · Coordinates ordered measurement stages and lifecycle state
src/engines/LoadNetworkEngine/index.ts
Data & Config
Derived metrics, thresholds, and shared helpers
- Results · Stateful results model exposed during and after a run
src/Results/index.ts - Metrics · Computes latency, jitter, bandwidth, packet loss, and duration
src/Results/MeasurementCalculations.ts - Scores · Derives final AIM-style scores from measured values
src/Results/ScoresCalculations.ts - Defaults · Public and internal default settings for requests, ramps, and thresholds
src/config/defaultConfig.ts - Internal Config · Normalized configuration shape used by engines and orchestration
src/config/internalConfig.ts - Numbers · Numeric selection and reduction helpers
src/utils/numbers.ts - Thresholds · Scales thresholds and sample-window decisions
src/utils/scaleThreshold.ts - Final Log · Structured final-result logging for diagnostics and display
src/logging/logFinalResults.ts
App & Examples
Browser app and integration examples
- Browser App · Edge-deployed demo and likely production web shell for the speed test
app/app.js - Basic Page · Minimal static integration example
example/basic-page/index.html - TURN Worker · Worker-based TURN credential example for packet-loss support
example/turn-worker/src/index.ts
Tests & CI
Validation and release automation
- Unit Tests · Checks config, math, results, and URL construction
tests/unit/Results/Results.test.ts - E2E Test · Browser-driven end-to-end measurement flow validation
tests/e2e/speedtest.test.ts - CI & Release · Build, publish, and security workflows for the package and app
.github/workflows/build.yml
Connections 26
- SpeedTest → Load Network: starts · Public API delegates test execution to the orchestrator
- SpeedTest → Results: exposes · Consumers read progress and final measurements from results
- SpeedTest → Defaults: configures · Test behavior is driven by default and user-supplied config
- SpeedTest → Final Log: logs · Final summary output is produced for diagnostics or display
- Load Network → Engine: uses · Orchestration is built on the shared engine contract
- Load Network → Reachability: stage · Reachability is one of the ordered measurement stages
- Load Network → Latency: stage · Latency is sequenced as part of the measurement plan
- Load Network → Bandwidth: stage · Bandwidth measurements run within the ordered plan
- Load Network → Packet Loss: stage · Packet loss is an optional measurement stage
- Bandwidth → Numbers: reduces · Bandwidth calculations rely on numeric reduction helpers
- Bandwidth → Thresholds: tunes · Ramp and sampling behavior use threshold scaling
- Packet Loss → TURN Worker: depends on · Packet loss requires TURN credential infrastructure from the consumer
- Results → Metrics: derives · Raw measurement points are turned into metrics
- Results → Scores: scores · Final scores are computed from derived metrics
- Metrics → Numbers: uses · Metric selection and reduction use math helpers
- Metrics → Thresholds: uses · Windowing and threshold decisions rely on scaling logic
- Defaults → Internal Config: normalizes · Defaults are shaped into the internal runtime config
- Browser App → SpeedTest: consumes · Browser app wraps the library runtime
- Basic Page → SpeedTest: demonstrates · Minimal usage example of the public API
- TURN Worker → Packet Loss: enables · Example wiring for the WebRTC/TURN packet-loss path
- Unit Tests → Defaults: verifies · Unit tests cover configuration defaults and internals
- Unit Tests → Metrics: verifies · Unit tests cover derived metric calculations
- Unit Tests → Numbers: verifies · Unit tests cover numeric helper behavior
- E2E Test → Load Network: verifies · End-to-end test exercises the full orchestrated flow
- CI & Release → Unit Tests: runs · CI validates the library with unit coverage
- CI & Release → E2E Test: runs · CI runs browser integration coverage