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

@magmacomputing/tempo-plugin-geo

v1.2.0

Published

Tempo community plugin for IP geolocation lookup, browser hardware location services, and coordinate resolution.

Downloads

388

Readme

Tempo Plugin

@magmacomputing/tempo-plugin-geo

A Community plugin for the Tempo ecosystem that provides IP geolocation lookup, browser hardware location services, coordinate normalization, and 24-hour cached coordinate stashing.

By keeping geolocation logic in this plugin, core @magmacomputing/tempo remains zero-network and purely deterministic.

👉 View the full documentation on our GitHub Pages


Installation

npm install @magmacomputing/tempo-plugin-geo

Usage

1. Fluent OOP with Namespaced Tempo.geo

Installing GeoPlugin mounts an immutable, locked-down Tempo.geo namespace onto the Tempo class:

import { Tempo } from '@magmacomputing/tempo';
import { GeoPlugin } from '@magmacomputing/tempo-plugin-geo';

Tempo.use(GeoPlugin);

// 1. Universal Geolocation Lookup (cached for 24h)
const lookupResult = await Tempo.geo.lookup();
console.log(lookupResult.lat, lookupResult.lng, lookupResult.city);

// 2. Inspect Current Ambient / Global Coordinates
console.log(Tempo.geo.current); // { latitude: ..., longitude: ..., city: ... }

// 3. Force Fresh Network Lookup (bypassing 24h cache)
const fresh = await Tempo.geo.lookup({ refresh: true });

// 4. Enrich a Tempo Instance Asynchronously
const t = new Tempo();
const localTime = await t.geoLocate();
console.log(localTime.geo?.latitude, localTime.geo?.longitude);

2. Functional Tree-Shakeable APIs

All underlying utilities can be imported as standalone tree-shakeable functions without augmenting Tempo:

import { Tempo } from '@magmacomputing/tempo';
import {
  geoLookup,
  resolveGeoCoordinates,
  stashGeo,
  clearStashedGeo,
  getStashedGeo,
} from '@magmacomputing/tempo-plugin-geo';

// Standalone lookup & instance creation
const coords = await geoLookup();
const t = new Tempo('2026-06-21', { geo: coords });

The Tempo.geo API Surface

| Method / Property | Description | | :--- | :--- | | Tempo.geo.lookup(opts?) | Universal geolocation lookup (browser hardware GPS or server IP lookup) cached for 24h. Supports { refresh: true }. | | Tempo.geo.resolve(input, opts?) | Asynchronously resolves coordinates from an instance, configuration, or ambient storage cache. | | Tempo.geo.coerce(input) | Pure function normalizing various coordinate formats (lat/lng, latitude/longitude, etc.) into a canonical GeoConfig. | | Tempo.geo.stash(coords, ttl?, keyOrOpts?) | Stashes coordinates in storage with an optional custom TTL (default: 24h) and multi-tenant partitioning. | | Tempo.geo.clear(keyOrOpts?) | Purges stashed coordinates from storage. | | Tempo.geo.get(keyOrOpts?) | Reads stashed coordinates for the specified tenant/IP or ambient default. | | Tempo.geo.current | Read-only getter returning the active global/ambient coordinates snapshot (getStashedGeo() ?? Tempo.config.geo). | | Tempo.geo.server(opts?) | Low-level server-side IP geolocation handler. | | Tempo.geo.browser(opts?) | Low-level browser Geolocation API handler. |


⚠️ Critical Operational Warnings

1. Server Context vs. Client Context

[!WARNING] Ambient IP lookup on a server resolves the SERVER's location, NOT the user's location.

  • In a server environment (Node.js, Deno, Bun, Edge runtimes), calling Tempo.geo.lookup() without options will query the datacenter's public outbound IP address.
  • If your server runs in AWS us-east-1 (Virginia) and an Australian user hits your API, calling ambient Tempo.geo.lookup() will resolve to Virginia!
  • Best Practice for Backends:
    • Always extract the client IP from trusted reverse proxy headers (e.g., X-Forwarded-For, CF-Connecting-IP) and pass it explicitly:
      const userCoords = await Tempo.geo.lookup({ ip: clientIp });
      const userTime = new Tempo(date, { geo: userCoords });
    • Or receive explicit GPS/browser coordinates from the frontend client request payload.

2. Multi-Tenant Key Isolation

[!CAUTION] Unpartitioned ambient storage is shared. In multi-tenant environments, always use unique keys or instance-level options.

  • Ambient storage stores coordinates under _magma_geo_ by default.

  • In a shared process or server handling requests for multiple tenants or distinct users, calling stash() or ambient lookup() without a key will cause tenants to overwrite each other's cached coordinates!

  • Solution A: Multi-Tenant Key Scoping: Pass a tenant identifier or user ID as the key:

    // Stash coordinates partitioned for tenant A:
    Tempo.geo.stash(tenantACoords, undefined, 'tenant-alpha');
    
    // Lookup / retrieve for a specific tenant:
    const coords = Tempo.geo.get('tenant-alpha');
    Tempo.geo.clear('tenant-alpha');

    The cache automatically partitions keys under _magma_geo_:<tenant-id>, guaranteeing strict isolation.

  • Solution B: Instance-Level Configuration (Recommended): Avoid ambient storage altogether by binding coordinates directly to Tempo instances:

    const tenantTime = new Tempo(date, { geo: tenantCoords });

    Instance-level coordinates are completely local, immutable, and never touch shared memory or ambient caches.


Security & Immutability

In keeping with Tempo's strict immutability principles, the Tempo.geo namespace is fully locked down:

  • Deeply Frozen: The entire Tempo.geo namespace and its attached utilities are recursively frozen.
  • Tamper-Proof: Protected against modification, deletion, or monkey-patching. Any attempt to reassign Tempo.geo or mutate its methods (e.g. Tempo.geo.lookup = ...) will throw a TypeError in strict mode.
  • Pure Instance Operations: Instance methods like t.geoLocate() always return a new, enriched Tempo instance, preserving the immutability of the original instance.

Licensing

This is a Community plugin. It is completely free and open-source for personal and commercial use under the MIT license.