npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@subspacecom/echo-test

v0.1.5

Published

A JS lib to be used with Subspace's WebRTC echo server

Readme

Echo test JS library

This library should be used with an Echo Server. This will automate the creating of multiple WebRTC connections to the Echo Server and calculate which one is the fastest by using a DataChannel.

Echo Server

We have an echo server implementation available but you can use any WebRTC server that echos back the data sent on the DataChannel.
This server needs to be able to receive an SDP offer on the /offer HTTP endpoint and return an SDP answer. It also needs to echo back the information received on the DataChannel.

Installing and using the lib

Install

npm install --save @subspacecom/echo-test
# or
yarn add @subspacecom/echo-test

Basic usage

The basic usage of the lib requires 2 parameters: an array of the RTCConfigs that need to be tested, and the echo test options. Example: echo(rtcConfigs, options).

  import { echo } from '@subspacecom/echo-test';

  const rtcConfigs = [
    { iceServers: [{ urls: ['stun:stun.l.google.com:193028'] }] },
    { iceServers: [{ urls: ['stun:global.stun.twilio.com:3478'] }] },
  ]

  const options = {
    signalUrl: 'https://echo-server-url.here/offer',
  }

  echo(rtcConfigs, options)
    .then(console.log)
    .catch(console.error)

The output to this call should be similar to this:

{
  "sorted": [
    [
      { "iceServers": [{ "urls": ["stun:stun.l.google.com:193028"] }] },
      {
        "iceGatheringTime": 221,
        "iceConnectionTime": 94,
        "avgRTT": 41.7
      }
    ],
    [
      { "iceServers": [{ "urls": ["stun:global.stun.twilio.com:3478"] }] },
      {
        "iceGatheringTime": 468,
        "iceConnectionTime": 134,
        "avgRTT": 50
      }
    ]
  ],
  "failed": [],
  "totalTime": 1274
}

After that it's up to you on how to use it.
The easy route is to use the first configuration from the sorted key. Entries are already sorted from faster to slower by avgRTT (average measured RoundTripTie), since latency is one major factor affecting a WebRTC connection's quality. If you want to, you could change the way the items are sorted accordingly to your own criteria. For example, consider using the historically more stable configuration even when the current estimated latency is slightly worse.

Options

| Parameter | Type | Required | Default | Description | | - | - | - | - | - | | signalUrl | string | yes | undefined | This is the HTTP endpoint of the echo server, something like https://your-url.com/offer. | | timeout | number | no | 2500 ms | This parameter limits the time that the test will run for. Once the limit is reached it will return all the successful tests under sorted and all unfinished or failed tests under failed. | | iceTimeout | number | no | 1000 ms | This is the total time that the peer will have to connect. This goes from the Peer creation to the ICE gathering and ICE connection completion. | | dataTimeout | number | no | 100 ms | This represents the timeout for each of the requests made over the DataChannel. When it times out the defined value is added to the average calculation. | | requests | number | no | 10 | This is the amount of times data will be sent using the DataChannel before calculating the average. | | sorter | function | no | (a, b) => a.avgRTT - b.avgRTT | This function is used to sort the best configuration using the data exchanged. In addition to the avgRTT, the props also have the iceGatheringTime, iceConnectionTime, and the rtcConfig which is the original configuration used to start the test. See Examples. |

Sorter examples

Giving the Subspace configuration a 15ms advantage over the other:

const isSubspace = (rtcConfig: RTCConfiguration) => {
  return !!rtcConfig.iceServers?.find((iceServer) => iceServer.urls.includes('subspace.com'));
}

const sorter = (a, b) => {
  const aAdvantage = isSubspace(a.rtcConfig) ? 15 : 0;
  const bAdvantage = isSubspace(b.rtcConfig) ? 15 : 0;

  return (a.avgRTT - aAdvantage) - (b.avgRTT - bAdvantage);
}

// Then pass the sorter on the echo configuration.

Giving the Subspace configuration a 10% advantage over the other:

const isSubspace = (rtcConfig: RTCConfiguration) => {
  return !!rtcConfig.iceServers?.find((iceServer) => iceServer.urls.includes('subspace.com'));
}

const sorter = (a, b) => {
  const aAdvantage = isSubspace(a.rtcConfig) ? (a.avgRTT * 0.1) : 0;
  const bAdvantage = isSubspace(b.rtcConfig) ? (b.avgRTT * 0.1) : 0;

  return (a.avgRTT - aAdvantage) - (b.avgRTT - bAdvantage);
}

// Then pass the sorter on the echo configuration.

Contributing

Dependencies

Install yarn. We also recommending using nvm with deeper shell integration.

Install the dependencies by running yarn.

Running it locally

When you're running it locally you're actually running an example app that imports the library.
It's a good idea to use it to develop and test the lib but the compilation process is different from the publish one.

  • Start the build watch with yarn start.
  • Test it with yarn test:watch.
  • The pre commit should fix the lint errors automatically, but you can use the yarn lint:fix if you want to do it manually.

Note: When a html or css file is changed you need to restart the server or manually run the yarn copy command

Building and testing

Those commands are meant to be used by the CI/CD and before publishing the lib. You don't need to run any of them manually.

  • Build the lib with the yarn build command.
  • Test it with yarn test, it will also run the test coverage and display it by the end of the tests. An lcov report is also exported.
  • Check for lint errors with yarn lint.

Publishing

When publishing, the app will be built and tested to avoid errors. Publish it with yarn publish --access public.