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

@oraculi/telematics-sdk

v0.1.3

Published

Telematics SDK for React Native

Readme

@oraculi/telematics-sdk

Telematics SDK for React Native (Nitro Modules).

Installation

npm install @oraculi/telematics-sdk react-native-nitro-modules
cd ios && pod install

Autolinking is enabled by default with the React Native CLI. If autolinking is disabled, follow the React Native manual linking guide and point iOS to TelematicsSdk.podspec and Android to node_modules/@oraculi/telematics-sdk/android.

Permissions

iOS (Info.plist):

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription
  • NSMotionUsageDescription
  • UIBackgroundModes with location (required for background tracking)
    • Trip notifications request notification permission at runtime when enabled.

Android (AndroidManifest.xml):

  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.ACCESS_BACKGROUND_LOCATION (Android 10+, requested by the SDK)
  • android.permission.POST_NOTIFICATIONS (Android 13+ for trip notifications)
  • android.permission.FOREGROUND_SERVICE
  • android.permission.FOREGROUND_SERVICE_LOCATION

Note: The SDK always requests background location permission to enable background tracking.

Usage

import {
  configure,
  requestPermission,
  startTracking,
  stopTracking,
  addListener,
  removeListener,
} from '@oraculi/telematics-sdk';

configure({
  apiKey: 'demo-key',
  trackingMode: 'driving',
  syncIntervalMinutes: 15,
});

await requestPermission();
startTracking();

const subId = addListener('scoreUpdated', ({ score }) => {
  console.log('Score', score?.safetyScore);
});

// Later
removeListener(subId);
stopTracking();

Presets

You can pass a preset string to apply a preconfigured setup. Any explicit fields you pass override the preset defaults. Use preset: 'none' to skip preset defaults entirely. If you omit preset, the SDK defaults to none (fully customizable).

configure({
  preset: 'ride_hailing',
  apiKey: 'demo-key',
});

Available presets:

  • ride_hailing (high accuracy, always-on tracking)
  • delivery (balanced accuracy, always-on tracking)
  • car_rental (driving-only tracking, lower sampling)
  • insurance (high accuracy, driving-only tracking)

Initialization

The SDK initializes itself by calling a native-only init endpoint using the apiKey. Initialization is asynchronous, and tracking won't start until the init endpoint returns a 2xx response. If init fails, startTracking() is a no-op and getTrackingState().lastError is populated.

The SDK posts to:

  • https://backoffice.speezydev.com/api/api-keys/verify (POST)

Headers:

  • Content-Type: application/json
  • x-api-key: <apiKey>

Sync (trip uploads)

Trips are submitted to:

  • https://backoffice.speezydev.com/api/trips (POST)

Headers:

  • Content-Type: application/json
  • x-api-key: <apiKey>

Payload shape (top-level):

  • externalId: trip id
  • startedAt: ISO string
  • endedAt: ISO string (optional)
  • distanceKm: number
  • payload: full telematics payload (trip/events/samples)

Events

Supported events:

  • tripStarted
  • tripEnded
  • scoreUpdated
  • syncState
  • initState (message is pending, ready, or failed)
  • error (emitted when lastError changes)

Error payloads include errorCode (stable identifier) and errorMessage (human-readable). Common codes: not_initialized, permission_denied, init_missing_api_key, init_invalid_endpoint, init_payload_failed, init_failed, location_error, context_unavailable (Android only).

Trip notifications

By default, the SDK posts local notifications when a trip starts, is in progress, and ends. Disable them by setting tripNotificationsEnabled: false if you want to provide your own notifications.

Example app

The example app lives in examples/react-native and installs the published SDK from npm.

  • Update the API key in examples/react-native/App.tsx.
  • The SDK is wired to the backoffice endpoints above; change the native endpoint constants if you need a different backend.
  • Run the app using the steps in examples/react-native/README.md.

Shared core

The shared C++ core lives in packages/telematics-core/cpp and is used by native targets via CMake (Android) and CocoaPods (iOS). This keeps the core logic reusable for the future Swift SDK.

API Reference

TelematicsConfig

  • apiKey?: string (required for init)
  • preset?: string (ride_hailing, delivery, car_rental, insurance, or none; default: none)
  • trackingMode?: 'driving' | 'always' | 'manual' (default: driving)
  • accuracy?: 'low' | 'balanced' | 'high' (default: balanced)
  • syncIntervalMinutes?: number (default: 15, minimum: 15, maximum: 1440)
  • retentionDays?: number (default: 30)
  • scoringWeights?: { braking?: number; accel?: number; speeding?: number; phoneUse?: number; cornering?: number }
    • defaults: braking 5, accel 5, speeding 3, phoneUse 8, cornering 3
  • efficiencyWeights?: { idling?: number; routeEfficiency?: number }
    • defaults: idling 40, routeEfficiency 60
  • sampleIntervalMs?: number (default: 1000, minimum: 250)
  • sampleDistanceMeters?: number (default: 5)
  • sampleMaxPoints?: number (default: 1800, clamped to 0..10000)
  • distanceFilter?: number (meters; overrides the base native distance filter)
  • locationUpdateIntervalMs?: number (minimum time between location updates; Android native, iOS throttled)
  • locationElasticityEnabled?: boolean (default: true)
    • when true, tightens distance/time filters as speed increases
  • locationFilterEnabled?: boolean (default: false)
    • enables C++ location smoothing + acceptance gating before trip/event detection
  • locationFilterUseKalman?: boolean (default: true)
  • locationFilterMinDistanceMeters?: number (default: 3)
  • locationFilterMaxAccuracyMeters?: number (default: 50)
  • locationFilterMaxSpeedMps?: number (default: 55)
  • locationFilterSpeedWindowSize?: number (default: 5)
  • locationFilterHeadingWindowSize?: number (default: 5)
  • autoTripDetectionEnabled?: boolean (default: true)
    • set to false to disable automatic trip start/end detection
  • walkingModeEnabled?: boolean (default: false)
    • lowers the movement threshold for walking or mixed travel tests
  • tripNotificationsEnabled?: boolean (default: true)
    • set to false to disable built-in trip notifications
  • manualTripControlEnabled?: boolean (default: false)
    • debug-only: when true, startTracking() begins a trip and stopTracking() ends it

Methods

  • configure(config: TelematicsConfig): void
    • Non-blocking; triggers native initialization and applies config.
  • requestPermission(): Promise<PermissionStatus>
  • checkPermission(): PermissionStatus
  • startTracking(): void
    • No-op if init has not succeeded or permission is denied.
  • stopTracking(): void
  • getTrackingState(): TrackingState
  • getTripHistory(limit?: number): TripSummary[]
  • getCurrentTrip(): TripSummary | undefined
  • getCurrentScore(): DrivingScore | undefined
  • syncNow(): Promise<boolean>
    • Returns false if init has not succeeded.
  • deleteLocalData(): void
  • addListener(event: TelematicsEvent, callback): string
  • removeListener(subscriptionId: string): void

Data models

  • TrackingState: { isTracking, lastError?, lastPosition?, permission }
  • LocationPoint: { latitude, longitude, speedMps?, accuracyM?, timestampMs }
  • TripSummary: { tripId, startTime, endTime?, distanceMeters, durationSeconds, avgSpeedMps, maxSpeedMps, safetyScore, efficiencyScore?, events? }
  • DrivingEvent: { type, timestamp, lat, lng, speedMps?, severity? }
  • DrivingScore: { safetyScore, efficiencyScore?, factors }
  • TelematicsEventPayload: { trip?, score?, message?, errorCode?, errorMessage? }

Background behavior

  • iOS: Significant Location Changes + stationary geofence are used for low-power wakeups. If the user force-quits the app, iOS will not relaunch it for location events.
  • iOS requires "Always" location permission for background tracking; "When In Use" stops updates.
  • Android: Foreground service keeps tracking active. If the user force-stops the app, tracking and uploads stop until the app is opened again.

Troubleshooting

Initialization fails

  • Ensure apiKey is set in configure().
  • Verify the native init endpoint returns 2xx.
  • Check network connectivity and TLS configuration.
  • If you are still using the dummy endpoint, replace it in native code.

Permission denied

  • iOS: confirm Info.plist keys are present and permissions were granted.
  • iOS: requestPermission() will attempt to upgrade When In Use -> Always if needed.
  • Android: ensure location permissions are in the manifest and approved at runtime.
  • Background location permission is required for tracking while the app is in the background.

No trips recorded

  • Make sure startTracking() is called after requestPermission() resolves.
  • Confirm init has succeeded (no lastError and startTracking() is not a no-op).
  • Trips require movement; verify on a device with GPS and motion.
  • For walking or mixed travel tests, set walkingModeEnabled: true.
  • For debug-only manual trips, set manualTripControlEnabled: true and use start/stop.

Sync not happening

  • Init must succeed before sync can run.
  • syncIntervalMinutes must be > 0 (minimum 15).
  • Call syncNow() to force a run and inspect the result.

Unexpected battery drain

  • Use accuracy: 'balanced' unless high precision is required.
  • Consider longer sampling intervals and distances for low-frequency use cases.

FAQ

Q: Can I disable presets? A: Yes. Omit preset or set preset: 'none'.

Q: Can I call configure() more than once? A: Yes. The SDK applies the latest config and re-runs initialization.

Contributing

License

MIT


Made with create-react-native-library