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

@geoseal/cordova

v0.2.1

Published

Geoseal location / geofence / ingest SDK for Apache Cordova (iOS + Android). A thin bridge over the @geoseal/capacitor native cores; all detection logic runs server-side.

Readme

@geoseal/cordova

Geoseal location / geofence / ingest SDK for Apache Cordova (iOS + Android). Plugin id: checkpoint-cordova-plugin. The SDK is a sensor; all detection logic runs server-side.

A thin bridge over the Geoseal native cores:

| Layer | iOS | Android | | --- | --- | --- | | Native engine | CheckpointCore pod (GeofenceManager) | dev.checkpoint:checkpoint-core AAR (GeofenceStore + receivers/services) | | Bridge | ios/CheckpointCordova.swift (CDVPlugin) | android/CheckpointCordova.java (CordovaPlugin) | | JS | www/checkpoint.js — generated by npm run build from src/index.ts, which single-sources the REST/presence layer from @geoseal/capacitor/core | same |

The JS module clobbers window.Checkpoint: the Checkpoint facade methods (init / isConfigured / setTrackingMode / getTrackingMode / getTrackingDirective / setDeviceTrackingMode) at the top level, plus every named export (NativeGeofence, mintDeviceToken, pullArmedFences, ingestFix, reportTrackingOutages, …) namespaced on the same object.

Requires cordova-android >= 12 and cordova-ios >= 8 (the Swift bridge targets the Cordova 8 plugin API).

Install

cordova plugin add @geoseal/cordova

The plugin's plugin.xml declares the native cores (<podspec> pod CheckpointCore ~> 0.1, which resolves from the CocoaPods trunk (CDN); <framework> dev.checkpoint:checkpoint-core:0.1.0).

  • iOS — no manual steps: CheckpointCore is live on the CocoaPods trunk, so cordova platform add ios resolves it from the CDN. On a machine with a stale CDN cache, run pod install --repo-update once in platforms/ios.

  • Androiddev.checkpoint:checkpoint-core is not on Maven Central yet; one-time per machine, publish the core AAR into ~/.m2 (the plugin ships a gradleReference that adds the content-filtered mavenLocal repo — remove it once the coordinate is published):

    cd node_modules/@geoseal/capacitor/android-core && ./gradlew publishToMavenLocal

    (No copy of @geoseal/capacitor handy? npm i --no-save @geoseal/capacitor in the app first, or use a monorepo checkout: <checkout>/packages/checkpoint-capacitor/android-core.)

From-checkout install (development)

# 0. One-time per machine — build the JS bundle + the Android core into ~/.m2:
cd <checkout>/packages/checkpoint-capacitor && npm install --no-save   # builds dist/ (prepare)
cd <checkout>/packages/checkpoint-cordova   && npm install --no-save && npm run build
cd <checkout>/packages/checkpoint-capacitor/android-core && ./gradlew publishToMavenLocal

# 1. Add the plugin from the local path:
cordova plugin add <checkout>/packages/checkpoint-cordova

iOS still resolves CheckpointCore from the CDN; to pin the checkout's copy instead, swap the generated platforms/ios/Podfile line for pod 'CheckpointCore', :path => '<checkout>/packages/checkpoint-capacitor' and re-run pod install (note: cordova plugin add/rm regenerates the Podfile, so re-apply the :path line after plugin changes; cordova prepare/build leave it alone).

iOS setup (app responsibilities)

  1. Info.plist usage strings — the app owns its user-facing copy; add to config.xml (the plugin deliberately does not overwrite these):

    <platform name="ios">
      <edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
        <string>Used to confirm on-site presence during a shift.</string>
      </edit-config>
      <edit-config file="*-Info.plist" mode="merge" target="NSLocationAlwaysAndWhenInUseUsageDescription">
        <string>Background location powers automatic arrival/departure detection.</string>
      </edit-config>
      <edit-config file="*-Info.plist" mode="merge" target="UIBackgroundModes">
        <array><string>location</string></array>
      </edit-config>
    </platform>

    (NSLocationAlwaysUsageDescription may be added too for older tooling; iOS 11+ reads the AndWhenInUse key.)

  2. Cold-relaunch revive (R2) — when iOS relaunches the app in the background for a location event, revive the engine without waiting for JS. In the app's AppDelegate.swift (or a small plugin/hook of your own):

    import CheckpointCore
    
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if launchOptions?[.location] != nil {
            GeofenceManager.shared.reviveForBackgroundLaunch()
        }
        return true
    }

    The plugin's deployment-target preference (14.0) and SwiftVersion are injected into config.xml automatically.

Android setup

Nothing manual: the engine AAR's manifest already carries the permissions (fine/coarse/background location, notifications, foreground-service location, boot) and the engine's receivers/services; the manifest merger brings them into the app. The runtime prompts are driven through the plugin (requestAlwaysAuthorization two-step foreground → "Allow all the time" escalation with fence re-registration on grant, requestBatteryExemption for Doze/OEM app-standby).

Usage

document.addEventListener("deviceready", async () => {
  // Layer 2 — REST transport (inert if any cred is missing; check isConfigured()).
  Checkpoint.init({
    baseUrl: "https://<project-ref>.supabase.co",
    anonKey: "<anon key>",
    publishableKey: "pk_…",
  });
  if (!Checkpoint.isConfigured()) return;

  // Layer 1 — native engine (persists creds for background relaunch POSTs).
  await Checkpoint.NativeGeofence.configure({
    baseUrl: "https://<project-ref>.supabase.co",
    anonKey: "<anon key>",
    publishableKey: "pk_…",
    subjectExternalId: "nurse-123",
    deviceId: "cordova-nurse-123",
    // Optional server directive fields: trackingMode / streamNow / minIntervalS
    // / maxStrayStreamS (stray-stream cap, default 600 s).
  });
  await Checkpoint.NativeGeofence.requestAlwaysAuthorization();
  await Checkpoint.NativeGeofence.requestNotificationAuthorization();
  await Checkpoint.NativeGeofence.requestBatteryExemption(); // Android; iOS no-op

  // Arm fences from the platform:
  const token = await Checkpoint.mintDeviceToken({ externalId: "nurse-123", deviceRef: "cordova-nurse-123" });
  const pull = await Checkpoint.pullArmedFences(token.subject_id);
  for (const fence of pull.regions) {
    await Checkpoint.NativeGeofence.addFence({
      id: fence.geofence_ref ?? fence.place_id,
      latitude: fence.center.latitude,
      longitude: fence.center.longitude,
      radius: fence.radius_m,
      name: fence.name ?? undefined,
    });
  }

  // Live crossings while the webview is alive (background POSTs are native):
  await Checkpoint.NativeGeofence.addListener("regionEvent", (e) => {
    console.log(e.type, e.regionId, e.latitude, e.longitude); // 'enter' | 'exit' | 'update' | 'stray_stream_stopped'
  });
});

Contract

The wire contract is FROZEN and mirrored from @geoseal/capacitor (src/definitions.ts): TrackingMode = 'geofence' | 'always' | 'off', the RegionEvent shape (4-value type union; stray_stream_stopped carries regionId: "" + the last off-site fix), the NativeDiagnostics field set, the directive RPC body (always all three p_ keys), and the /v1/ingest body shape. test/conformance.spec.ts pins it — verified by npm run typecheck:test (a drift is a compile error, since the types come from @geoseal/capacitor/core itself).

Developing

  • src/ is the TypeScript source; www/checkpoint.js is a committed build artifact (Cordova installs plugins as plain files — no npm lifecycle). After editing src/, run npm run build (typecheck + fixture typecheck + esbuild bundle) and commit the regenerated bundle.
  • The geofence-only entry point of the reference SDK (@geoseal/capacitor/geofence) has no Cordova analog: Cordova js-modules are single-file clobbers, not subpath exports. Privacy-first dtok_-only embeds should simply not call the streaming/self-serve helpers.

License

Apache-2.0 (matches the monorepo and the native cores).