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 🙏

© 2024 – Pkg Stats / Ryan Hefner

re.places.js

v0.1.3

Published

A serverless database of 41,000 global cities for your browser. Designed as a light-weight polyfill for ‘cities’ from Algolia's places API, ahead of the service’s sunset in May 2022. It also runs standalone.

Downloads

18

Readme

Re:Places.js

Ok, so still not quite on par with the amazing <Algolia-Places> ...

re:places is a serverless database of 41,000 global cities for your browser. Designed as a light-weight polyfill for ‘cities’ from Algolia's Places API, ahead of the service’s sunset in May 2022. It also runs standalone.

Try it out: Search a city [demo]

Install

  1. Standalone install [demo]
  2. Polyfill Algolia Places API [demo]
  3. Self hosted

Some basic features

  • Faster than you need; a round-trip query averages 20-30ms[^1]
  • Lazy-load the global cities database in under 400kB[^2] over the wire
  • Filter by country to optimise file size: France weighs in at 20kB[^2] and Australia comes in under 5kB[^2]
  • Filter results based on a user's IP, proximity to a lat,lng, or the area inside a polygon or bounding box
  • Standalone, or as a zero-config proxy to extend the life of Algolia's Places.js (beyond their API shutdown)
  • Entirely static, nothing required beyond your favourite CDN or storage bucket
  • Entirely free and open source (code is MIT licensed, database is CC BY 4.0)[^3]
  • Contributions celebrated 🎉

Installation & Use

re:places.js is currently intended to be installed from a CDN, with the exception of the polyfill (service worker) script. While modules are in use, they rely on remote imports. This is primarily because the library was coded by hand, without a package manager, and so doesn't have any build steps that might facilitate different versions (UMD, local es6 modules, etc.) Future versions should resolve this shortcoming and provide for a straightforward npm i process. That said, porting the library to run local is trivial.

  1. Import re.places.js into your script (i.e. a module) or document
import replaces from 'https://cdn.jsdelivr.net/npm/[email protected]/re.places.js'
<script type="module" async src="https://cdn.jsdelivr.net/npm/[email protected]/re.places.js?global"></script>
  1. Search a city:
// this downloads the Australia database (5kb) and runs a search
replaces.search({
  query: 'Cairns',
  countries: ['au'],
})
.then(e => console.log(e));

Advanced setup

// you can provide default options that apply to every search
// refer to the algolia documentation for more info:
// community.algolia.com/places/documentation.html#reconfigurable-options
replaces.init({
  // preload the database
  preload: true,
  // limit it to France and Australia ~= 26Kb download
  countries: ['au', 'fr'],
  // by default we weight results by proximity to an IP location
  // (or at least Algolia do - this library limits it to country)
  // you can turn that off here .. but it's not great for user experience
  aroundLatLngViaIP: false,
  // specify a geo location and distance (in meters), instead of using the IP 
  aroundLatLng: '-16, 145',
  aroundRadius: 3000000, // =300km
  // any results outside this bounding box are excluded
  insideBoundingBox: '-10,154,-29,138',
  // any results outside this polygon are excluded
  insidePolygon: '-10,138,-10,154,-29,154,-34,152,-34,141,-29,138',
})

// any options you provide to a search are merged with your default options
const result = await replaces.search({
  query: 'ca',
  // for this search we want to weight by IP location (even though we turned it off above)
  aroundLatLngViaIP: true,
});
  1. Download re.places.algolia.js and place the file at the root of your app
  2. Import the library directly after Algolia Places.js, this will install a service worker to intercept any API calls
import 'https://cdn.jsdelivr.net/npm/[email protected]'
// import directly after places.js
import '/re.places.algolia.js'
  1. That's it. Test the <input> your previously set up for places.js

Polyfill with a service worker already in place

The above install will throw an error where a service worker is already installed on a domain. To resolve, import re.places.algolia.sw.js at the top of the existing service worker script. Re.Places only intercepts calls to the Algolia API and does not use any caching strategy. Imported at the top of your script it will work in tandem with any logic already in place.

  1. Edit your main service worker to add the following line to the top of the file
self.importScripts('https://cdn.jsdelivr.net/npm/[email protected]/src/re.places.algolia.sw.js')
// YOUR SERVICE WORKER LOGIC GOES HERE

Self hosted

To self-host the library, you can simply switch out the CDN hosted libraries for local versions. This involves ensuring you have a local copy of each script required for your setup, and replacing any remote urls with your local path. The library was originally built for local use, but later adapted to use a CDN due to the nature of the beast. Future iterations will allow for either approach.

  1. Download the repository or create a local fork
  2. npm install
  3. build the database npm run build-db
  4. search and replace all the remote imports with local paths (we use cdn.jsdelivr.net and all files should be in /, /src and /demo)
  5. test the demo pages npm run demo (you'll need HTTPS on localhost)

Further reading

Check out the source of the demo pages for more detailed explanations of each setup. The scripts themselves are also commented, but there's no guarantees as to coherence. Please feel free to submit an issue or PR to resolve any confusion. Thanks for reading!


re:places © 2022 theprojectsomething | MIT license | Github | Support the project Hand made with 🖤 in Cairns, Australia

[^1]: In Cairns, Australia, queries to the Algolia Places API average 250ms (and it feels nice!). With re:places the initial query will run slower due to lazy-loading the database (and an actual network connection being required!) ¯\(ツ)/¯ ... after that you're latency free. See the advanced setup for pre-loading instructions. [^2]: The included build script generates a brotli compressed global database weighing in at 396kB, useful for self hosting. CDN compression varies, e.g. ~480kB gzip from JSDelivr / 508kB br from unpkg [^3]: re:places depends on @lucaong/MiniSearch and @rowanwins/point-in-polygon-hao (both MIT / 0 dependencies).
The database is derived from the basic World Cities Database available from SimpleMaps.com (CC BY 4.0).
Ideas mixed in from @turfjs and this stackoverflow answer. Cloudflare's 1.1.1.1 supplies location hints.
Informing everything, of course, is the masterwork that is Algolia Places.
All amazing efforts. Thank you so much.