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

@ariel-mutebi/circle-discovery

v1.1.22

Published

Efficient POI discovery within a radius using barycentric fixed-mass search.

Downloads

2,301

Readme

circle-discovery

Efficiently discover all points of interest within a geographic circle, bypassing the 20-result limit of the Google Places Nearby Search API.

The problem

Google's Nearby Search API returns at most 20 results per query. For any area with more than 20 POIs — a city centre, a dense neighbourhood — you'll silently miss results. Naively subdividing the search area into a grid wastes API quota and still doesn't guarantee complete coverage.

How it works

circle-discovery adapts the Barycentric Fixed-Mass Method (Kamer, Ouillon & Sornette, 2013), a technique from multifractal analysis, into an adaptive spatial search. It works by:

  1. Querying a circle and finding the barycenter of the results
  2. Stabilizing the barycenter iteratively to locate the true density centre
  3. Computing a local density scale — the radius needed to capture ~20 places at the local density
  4. Expanding outward with sub-circles sized to that density scale, using a nonoverlapping coverage criterion to avoid redundant queries
  5. Repeating until the entire initial circle is covered

This means the algorithm self-calibrates: dense urban areas get small, tightly-packed sub-circles; sparse areas get large ones. API calls are never wasted on already-covered regions.

Installation

npm install @ariel-mutebi/circle-discovery

Usage

The package is agnostic about how you call the Google Places API. You provide a fetchPlaces function that takes a circle and returns a promise of places — the algorithm handles the rest.

Basic example

const restaurants = await subCircleSearch({
  initialCenter: { lat: 40.7128, lng: -74.0060 }, // New York
  initialRadius: 1000,
  fetchPlaces: async ({ center, radius }) => {
    // pass type filters through to your API call as needed
    return fetchNearbyPlaces({ center, radius, type: 'restaurant' });
  },
});

API

subCircleSearch(params)

Parameters

| Name | Type | Description | |------|------|-------------| | initialCenter | LatLng | Centre of the search area | | initialRadius | number | Radius of the search area in metres | | fetchPlaces | (circle: Circle) => Promise<Place[]> | Function that queries your places API |

Returns

Promise<Place[]> — deduplicated array of all places found within the initial circle.

Types

interface LatLng {
  lat: number;
  lng: number;
}

interface Circle {
  center: LatLng;
  radius: number;
}

interface Place {
  location?: LatLng;
  [key: string]: unknown; // any additional fields from your API
}

Considerations

API quota — the algorithm minimises calls through nonoverlapping coverage, but a large radius over a dense area will still generate many queries. Test with a small initialRadius first.

Rate limiting — if your fetchPlaces function needs to respect rate limits, handle that inside the function itself before returning results.

Radius unitsinitialRadius and all internal distance calculations are in metres. Make sure your fetchPlaces implementation uses the same unit.

Background

This algorithm is inspired by the Barycentric Fixed-Mass Method introduced in:

Y. Kamer, G. Ouillon, and D. Sornette, "Barycentric fixed-mass method for multifractal analysis", Physical Review E 88, 022922 (2013).

The key concepts adapted from that paper are barycentric pivot selection (centering queries on the true density centre of results) and nonoverlapping coverage (preventing redundant sampling of already-covered areas).