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

@bota-dev/react-native-sdk

v0.0.7

Published

Bota React Native SDK for BLE device communication

Downloads

744

Readme

@bota-dev/react-native-sdk

Official React Native SDK for Bota wearable devices.

Installation

npm install @bota-dev/react-native-sdk react-native-ble-plx
# or
yarn add @bota-dev/react-native-sdk react-native-ble-plx

iOS Setup

  1. Add Bluetooth permissions to ios/YourApp/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to Bota recording devices</string>
<key>UIBackgroundModes</key>
<array>
  <string>bluetooth-central</string>
</array>
  1. Install pods:
cd ios && pod install

Android Setup

  1. Add permissions to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Quick Start

import { BotaClient } from '@bota-dev/react-native-sdk';

// Initialize SDK
await BotaClient.configure({
  environment: 'production',
  logLevel: 'info',
});

// Wait for Bluetooth
await BotaClient.waitForBluetooth();

// Scan for devices
BotaClient.devices.on('deviceDiscovered', (device) => {
  console.log('Found device:', device.name);
});

BotaClient.devices.startScan();

// Connect to a device
const connectedDevice = await BotaClient.devices.connect(discoveredDevice);

// Provision with token from your backend
await BotaClient.devices.provision(connectedDevice, deviceToken, 'production');

// List recordings
const recordings = await BotaClient.recordings.listRecordings(connectedDevice);

// Sync a recording
for await (const progress of BotaClient.recordings.syncRecording(
  connectedDevice,
  recording,
  uploadInfo // from your backend
)) {
  console.log(`${progress.stage}: ${progress.progress * 100}%`);
}

API Reference

BotaClient

Main entry point for the SDK.

// Configure SDK
await BotaClient.configure({
  environment: 'production' | 'sandbox',
  backgroundSyncEnabled: boolean,
  wifiOnlyUpload: boolean,
  logLevel: 'debug' | 'info' | 'warn' | 'error' | 'none',
});

// Access managers
BotaClient.devices    // DeviceManager
BotaClient.recordings // RecordingManager
BotaClient.ota        // OTAManager

// State
BotaClient.state           // 'uninitialized' | 'initializing' | 'ready' | 'error'
BotaClient.bluetoothState  // 'unknown' | 'poweredOn' | 'poweredOff' | ...
BotaClient.isBluetoothReady

DeviceManager

Handles device discovery, connection, and provisioning.

// Scanning
BotaClient.devices.startScan({ timeout: 30000, deviceTypes: ['bota_pin'] });
BotaClient.devices.stopScan();
BotaClient.devices.getDiscoveredDevices();

// Connection
const device = await BotaClient.devices.connect(discoveredDevice);
await BotaClient.devices.disconnect(device);
BotaClient.devices.isConnected(deviceId);

// Provisioning
await BotaClient.devices.provision(device, token, 'production');
await BotaClient.devices.isProvisioned(device);

// Status
const status = await BotaClient.devices.getStatus(device);
const unsubscribe = BotaClient.devices.subscribeToStatus(device, (status) => {});

// Events
BotaClient.devices.on('deviceDiscovered', (device) => {});
BotaClient.devices.on('deviceConnected', (device) => {});
BotaClient.devices.on('deviceDisconnected', (deviceId, error) => {});
BotaClient.devices.on('deviceStatusUpdated', (deviceId, status) => {});

RecordingManager

Handles recording transfer and upload.

// List recordings on device
const recordings = await BotaClient.recordings.listRecordings(device);

// Sync a recording (transfer + upload)
for await (const progress of BotaClient.recordings.syncRecording(
  device,
  recording,
  uploadInfo
)) {
  // progress.stage: 'preparing' | 'transferring' | 'uploading' | 'completing' | 'completed' | 'failed'
  // progress.progress: 0.0 - 1.0
}

// Sync all recordings
for await (const progress of BotaClient.recordings.syncAllRecordings(
  device,
  async (recording) => {
    // Get upload info from your backend
    return await yourBackend.getUploadInfo(device.serialNumber, recording);
  }
)) {
  console.log(`Recording ${progress.recordingIndex}/${progress.totalRecordings}`);
}

// Upload queue management
BotaClient.recordings.getPendingUploads();
BotaClient.recordings.cancelUpload(taskId);
BotaClient.recordings.retryFailedUploads();
BotaClient.recordings.pauseUploads();
BotaClient.recordings.resumeUploads();

// Events
BotaClient.recordings.on('syncStarted', (uuid) => {});
BotaClient.recordings.on('syncCompleted', (uuid, recordingId) => {});
BotaClient.recordings.on('syncFailed', (uuid, error) => {});
BotaClient.recordings.on('uploadProgress', (taskId, progress) => {});

Types

interface DiscoveredDevice {
  id: string;
  name: string;
  deviceType: 'bota_pin' | 'bota_pin_4g' | 'bota_note';
  firmwareVersion: string;
  pairingState: 'unpaired' | 'pairing' | 'paired' | 'error';
  rssi: number;
}

interface ConnectedDevice {
  id: string;
  serialNumber: string;
  deviceType: DeviceType;
  firmwareVersion: string;
  isProvisioned: boolean;
  connectionState: ConnectionState;
  mtu: number;
}

interface DeviceStatus {
  batteryLevel: number;
  storageUsedPercent: number;
  state: DeviceState;
  pendingRecordings: number;
  lastSyncAt: Date | null;
  flags: DeviceFlags;
}

interface DeviceRecording {
  uuid: string;
  startedAt: Date;
  durationMs: number;
  fileSizeBytes: number;
  codec: AudioCodec;
}

interface UploadInfo {
  uploadUrl: string;      // Pre-signed S3 URL
  uploadToken: string;    // Upload token (up_*)
  recordingId: string;    // Recording ID (rec_*)
  completeUrl: string;    // URL to call when complete
  expiresAt: Date;
}

interface SyncProgress {
  stage: SyncStage;
  progress: number;
  bytesTransferred?: number;
  bytesUploaded?: number;
  totalBytes?: number;
  recordingId?: string;
  error?: string;
}

Error Handling

import {
  BotaError,
  BluetoothError,
  DeviceError,
  ProvisioningError,
  TransferError,
  UploadError,
} from '@bota/react-native-sdk';

try {
  await BotaClient.devices.connect(device);
} catch (error) {
  if (error instanceof BluetoothError) {
    // Handle Bluetooth errors
  } else if (error instanceof DeviceError) {
    // Handle device errors (connection, not found, etc.)
  } else if (error instanceof ProvisioningError) {
    // Handle provisioning errors
  }
}

Integration with Your Backend

The SDK does not communicate directly with the Bota API. Your mobile app should:

  1. Authenticate users through your own backend
  2. Call your backend to register devices and get device tokens
  3. Call your backend to create recordings and get upload URLs
  4. The SDK uploads directly to S3 using the pre-signed URLs

See the Bota API documentation for backend integration details.

License

MIT