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

@geoleaf-plugins/navigation

v1.0.3

Published

GeoLeaf navigation plugin

Readme

@geoleaf-plugins/navigation

Turn-by-turn guidance plugin for GeoLeaf JS. It follows the user's position along a route computed by @geoleaf-plugins/routing, announces the next manoeuvre, and recomputes when the user leaves the path.

Guidance is entered from the itinerary panel of @geoleaf-plugins/routing, once a route is computed. GeoLeaf.Navigation exposes the session (start, stop, isGuiding), its progress (onProgress) and the spoken announcements (setVoiceEnabled, isVoiceEnabled, isVoiceAvailable).


Installation

npm install @geoleaf-plugins/navigation @geoleaf-plugins/routing

Note — Prerequisites: @geoleaf/core and @geoleaf-plugins/routing must both be loaded before this plugin. Guidance without a computed route has no object, and the plugin declares that dependency rather than discovering it at runtime.


Quick start

import "@geoleaf-plugins/routing";
import "@geoleaf-plugins/navigation";

// After GeoLeaf.boot() — GeoLeaf.Navigation is available on globalThis.GeoLeaf.
// A listener may subscribe before any session: it is wired when guidance starts.
const unsubscribe = GeoLeaf.Navigation.onProgress((progress) => {
    console.log(progress);
});

Unlike routing, this plugin is meant to be loaded on demand. Guidance is only ever entered after a route has been computed — that is, from an interface already drawn by a plugin already loaded — so the constraint that forces routing to load eagerly does not apply here, and this is the heavier half of the two.


Configuration — modules.navigation

| Key | Type | Default | Meaning | | ------------------------- | --------- | ------- | ------------------------------------------------------------------ | | enabled | boolean | true | Turns the plugin on. | | showButton | boolean | false | Shows the toolbar entry point. | | arrivalRadiusMetres | number | 30 | Within this distance, a stop counts as reached. | | offRouteThresholdMetres | number | 40 | Beyond this distance from the line, a reading counts as off-route. | | confirmExit | number | 3 | Consecutive off readings needed to confirm a departure. | | confirmReturn | number | 2 | Consecutive on readings needed to confirm a return. | | retryAfterFixes | number | 2 | Fixes to wait before the first retry after a failed recomputation. | | maxRetryFixes | number | 8 | Ceiling on that wait, which doubles on each failure. | | voiceEnabled | boolean | true | Starting state of spoken announcements — switchable in session. | | voiceAnnounceAtMetres | number | 200 | How far ahead a manoeuvre is first announced. | | keepScreenAwake | boolean | true | Keeps the screen on while guidance runs. | | followZoom | number | 17.5 | Zoom held while following. Re-applied on every fix. | | followPitch | number | 60 | Tilt held while following, in degrees. Capped at 80 by the engine. | | cameraMaxTransitionMs | number | 1000 | Ceiling on a camera transition, in milliseconds. |

showButton defaults to false while there is no panel to open: a visible control that does nothing is worse than an absent one, because it does not announce itself — it gets clicked. Guidance is entered from the route, in the panel of @geoleaf-plugins/routing, because there is nothing to guide along until a route exists.

🛑 These thresholds live here and nowhere else. The engine modules take every one of them as a parameter and default none: a value written both in configuration and in the module that reads it diverges from the configuration without anything turning red, on a quantity nobody re-measures because both sides look authoritative.

⚠️ An out-of-range value falls back to its default — it is neither honoured nor thrown on. confirmExit: 0 is not a shorter confirmation, it is the ABSENCE of one: every noisy reading would become a confirmed departure, and a provider quota measured in requests per minute empties in minutes. offRouteThresholdMetres must also stay wider than arrivalRadiusMetres — a vehicle parked at a delivery is routinely further from the road than from the stop, and the two crossing would make every arrival read as a departure.


Platform access is confined to three adapters

The plugin reaches navigator.geolocation, speechSynthesis, navigator.wakeLock and the online event only from src/platform/. Everywhere else it consumes an adapter.

⚠️ The repository's gate names the first three; the online listener lives there too, although nothing forces it. The property being protected is not the gate's list — it is that a native port replaces those files and nothing else. A fourth browser API reached from elsewhere would break that while the gate stayed green, which is worse than having no gate at all.

This is the one structural property worth knowing about this package: it makes a later native port a matter of replacing three files rather than re-reading the plugin. The rule is enforced by a gate in the repository, not left to review.


Spoken guidance

A manoeuvre is announced once, when the driver comes within voiceAnnounceAtMetres of it. The starting state is voiceEnabled; it is switchable for the running session:

GeoLeaf.Navigation.setVoiceEnabled(false); // silences what is speaking, too
GeoLeaf.Navigation.isVoiceEnabled();
GeoLeaf.Navigation.isVoiceAvailable(); // hide your toggle when this is false

The switch is session-scoped by contract: every session starts again from the profile value. And isVoiceAvailable() exists so an interface can HIDE its toggle rather than grey it out — an engine without speech synthesis does not have the feature, and a greyed control says "this exists, but not for you", which is false.

⚠️ Turning announcements off cancels what is already speaking. A switch that only stopped future announcements would leave someone who just asked for quiet listening to the next twenty seconds of instructions — which reads as a control that does not work.


The screen stays awake

With keepScreenAwake (the default), guidance holds a screen wake lock for the length of a session, and re-takes it every time the page becomes visible again. That second half is the one that matters: browsers release the lock whenever the document is hidden — a call, a glance at a message, a locked phone — and coming back does not restore it. An implementation that asks once passes every test and lets the screen go dark in traffic.

The lock is a comfort and never a prerequisite: it is refused on an insecure origin, on a low battery, under a policy. Guidance never waits on it and never warns about it.


License

MIT © 2026 Mattieu Pottier