Skip to content

web4more/netinfo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Network Information API polyfill

🔌 navigator.connection polyfill for anywhere

📜 Implements the Network Information API
🗺️ Provides navigator.connection APIs
🚀 Easy to use with a drop-in import polyfill
🦄 Also has a ponyfill import too
💻 Works in Node.js
🌐 Works in the browser
🦕 Works in Deno
🧅 Works in Bun

👀 Looking for navigator.connection.saveData? Check out the related Save Data API polyfill at @webfill/savedata.

Installation

npm pnpm Yarn Deno Bun

You can install this polyfill using your favorite npm package manager like npm, pnpm, or Yarn:

npm install @webfill/netinfo

If you're using Deno you can use an npm: specifier and it should Just Work™:

import "npm:@webfill/netinfo";

If you want to go buildless in the browser you can use an npm CDN like esm.sh or esm.run:

<script type="module">
  import "https://esm.run/@webfill/netinfo";
  import "https://esm.sh/@webfill/netinfo";
</script>

⚠️ This polyfill requires an existing Navigator/navigator class/object to mutate and add the Network Information APIs to. If you're using Deno, Bun, the browser, or Node.js v21+ this is already available. If not, you'll need to add a Navigator/navigator polyfill.

Usage

Browser Node.js Deno Bun

⚠️ The values returned by this polyfill are best effort. It's always best to fail or degrade gracefully rather than check and assume.

This polyfill is a drop-in import that will add the Network Information APIs to the global scope's navigator object. Then you can use navigator.connection just like you would in a conforming browser environment:

import "@webfill/netinfo";

console.log(navigator.connection);
//=> {
//   downlink: 10,
//   downlinkMax: Infinity,
//   effectiveType: "4g",
//   rtt: 100,
//   type: "wifi",
// }

if (navigator.connection.rtt > 200) {
  alertBox.innerText = "You may experience some delay in game responsiveness.";
}

If you prefer to utilize the implementation directly without mutating the global scope, you can use the @webfill/netinfo/ponyfill import instead:

// This still delegates to the browser-native features if available.
import { NavigatorNetworkInformation } from "@webfill/netinfo/ponyfill";

const navigatorConnection = Reflect.get(
  NavigatorNetworkInformation.prototype,
  "connection",
  globalThis.navigator ?? {}
);

console.log(navigatorConnection);
//=> {
//   downlink: 10,
//   downlinkMax: Infinity,
//   effectiveType: "4g",
//   rtt: 100,
//   type: "wifi",
// }

if (navigatorConnection.rtt > 200) {
  alertBox.innerText = "You may experience some delay in game responsiveness.";
}

How it works

This polyfill uses periodic fetch() polling with performance.now() to guage the speed (or lack thereof) of your network connection. There's also a fallback to use a synchronous version if you do navigator.connection.rtt or something before the first polling interval has completed.

Development

TypeScript Vite

This project is written in TypeScript. You can run the tests in the browser using npm run test:browser or in Node.js using npm test.

The most interesting bits are getFetchStats(), guessNetInfo(), and src/lib/NetworkInformation.ts. That's where most of the magic happens.

Why not Vitest?

Vitest doesn't play well with Worker threads and Atomics.wait(). If you use @vitest/web-worker, it's the same thread and so it deadlocks. You can't use new Worker() either since you need a raw JavaScript file (not .ts). Thus, the easiest thing to do to test things is to just build it and test against the output JavaScript files instead of the TypeScript source code.

If you can figure out a way around this problem, I'd be very grateful! ❤️

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published