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

@superapp_men/voice-recorder-capacitor

v1.0.6

Published

Voice recorder with checkpoint support for Capacitor-based SuperApp Partner Apps

Readme

@superapp_men/voice-recorder-capacitor

Voice recorder with checkpoint support for SuperApp Partner Apps. This package provides a clean API for recording audio in partner apps that are hosted within a SuperApp environment, with native audio capture handled by the SuperApp.

Features

  • 🎙️ High-Quality Audio Recording - Native audio capture via SuperApp
  • 📍 Checkpoint Support - Create intermediate checkpoints during recording to segment audio
  • 🔄 Event-Driven Architecture - Real-time state updates and progress events
  • ⚙️ Configurable Audio Settings - Customize format (WAV/PCM), sample rate, bit depth, and channels
  • 🔐 Permission Management - Built-in permission checking and requesting
  • 📱 Cross-Platform - Works on iOS and Android via SuperApp
  • 🎯 TypeScript Support - Full TypeScript definitions included
  • 🐛 Debug Mode - Comprehensive logging for troubleshooting

Installation

npm install @superapp_men/voice-recorder-capacitor

Quick Start

Basic Usage

import {
  VoiceRecorder,
  RecorderState,
  AudioFormat,
  SampleRate,
} from "@superapp_men/voice-recorder-capacitor";

// Create a recorder instance
const recorder = new VoiceRecorder({
  timeout: 10000,
  debug: true,
});

// Check availability
const available = await recorder.isAvailable();
console.log("Recording available:", available);

// Request permission
const permission = await recorder.requestPermission();
if (permission !== "granted") {
  console.error("Permission denied");
  return;
}

// Start recording
await recorder.startRecording({
  audioConfig: {
    format: AudioFormat.WAV,
    sampleRate: SampleRate.SR_16000,
    bitDepth: 16,
    channels: 1,
  },
  maxDuration: 120000, // 2 minutes
});

// Stop recording
const result = await recorder.stopRecording();
console.log("Recording result:", result);
console.log("Audio data:", result.audioData); // Base64-encoded WAV

With Checkpoints

// Start recording with checkpoint mode enabled
await recorder.startRecording({
  isCheckpoints: true,
  audioConfig: {
    format: AudioFormat.WAV,
    sampleRate: SampleRate.SR_16000,
    bitDepth: 16,
    channels: 1,
  },
});

// Create checkpoints during recording
const checkpoint1 = await recorder.createCheckpoint();
console.log("Checkpoint 1:", checkpoint1.audioData);

// Continue recording...
const checkpoint2 = await recorder.createCheckpoint();
console.log("Checkpoint 2:", checkpoint2.audioData);

// Stop recording - result includes all checkpoints merged
const result = await recorder.stopRecording();
console.log("All checkpoints:", result.checkpoints);
console.log("Complete recording:", result.audioData); // Merged audio

Event Listeners

// Listen to state changes
recorder.on("stateChange", ({ state }) => {
  console.log("State changed:", state);
});

// Listen to progress updates
recorder.on("progress", ({ duration }) => {
  console.log("Recording duration:", duration, "ms");
});

// Listen to checkpoint creation
recorder.on("checkpointCreated", ({ checkpoint }) => {
  console.log("Checkpoint created:", checkpoint.index);
});

// Listen to errors
recorder.on("error", ({ message }) => {
  console.error("Error:", message);
});

API Reference

VoiceRecorder Class

Constructor

new VoiceRecorder(config?: VoiceRecorderConfig)

Config Options:

  • timeout?: number - Request timeout in milliseconds (default: 5000)
  • debug?: boolean - Enable debug logging (default: false)

Methods

isAvailable(): Promise<boolean>

Check if voice recording is available on the device.

const available = await recorder.isAvailable();
checkPermission(): Promise<PermissionStatus>

Check the current microphone permission status.

Returns: 'granted' | 'denied' | 'prompt' | 'unknown'

const status = await recorder.checkPermission();
requestPermission(): Promise<PermissionStatus>

Request microphone permission from the user.

const status = await recorder.requestPermission();
if (status === "granted") {
  // Permission granted
}
startRecording(config?: RecordingConfig): Promise<void>

Start a new recording session.

Config Options:

  • isCheckpoints?: boolean - Enable checkpoint mode (default: false)
  • audioConfig?: AudioConfig - Audio encoding configuration
  • maxDuration?: number - Maximum recording duration in milliseconds

AudioConfig:

  • format?: AudioFormat - Audio format: AudioFormat.WAV or AudioFormat.PCM (default: WAV)
  • sampleRate?: number - Sample rate in Hz (default: 16000)
  • bitDepth?: number - Bit depth: 8, 16, 24, or 32 (default: 16)
  • channels?: number - Number of channels: 1 (mono) or 2 (stereo) (default: 1)
await recorder.startRecording({
  isCheckpoints: true,
  audioConfig: {
    format: AudioFormat.WAV,
    sampleRate: SampleRate.SR_16000,
    bitDepth: 16,
    channels: 1,
  },
  maxDuration: 120000,
});
stopRecording(): Promise<RecordingResult>

Stop the current recording and return the result.

Returns:

{
  audioData: string;           // Base64-encoded WAV audio
  duration: number;            // Total duration in milliseconds
  size: number;                // Size in bytes
  timestamp: number;           // Completion timestamp
  audioConfig: AudioConfig;    // Audio configuration used
  checkpointCount: number;     // Number of checkpoints created
  checkpoints?: Checkpoint[];  // Array of checkpoints (if checkpoint mode)
}
createCheckpoint(): Promise<Checkpoint>

Create a checkpoint during recording (only available in checkpoint mode).

Returns:

{
  id: string; // Unique checkpoint ID
  index: number; // Checkpoint number (1-based)
  audioData: string; // Base64-encoded WAV audio segment
  duration: number; // Duration from start in milliseconds
  segmentDuration: number; // Duration of this segment in milliseconds
  size: number; // Size in bytes
  timestamp: number; // Creation timestamp
  audioConfig: AudioConfig; // Audio configuration used
}
getStatus(): Promise<RecordingStatus>

Get the current recording status.

getState(): RecorderState

Get the current recorder state.

Returns: 'idle' | 'requesting_permission' | 'ready' | 'recording' | 'paused' | 'stopped' | 'error'

isCurrentlyRecording(): boolean

Check if currently recording.

getDuration(): number

Get the current recording duration in milliseconds.

getCheckpoints(): Checkpoint[]

Get all checkpoints created during the current recording session.

on<T>(event: RecorderEventType, callback: EventListener<T>): () => void

Add an event listener. Returns an unsubscribe function.

Events:

  • 'stateChange' - Recorder state changed
  • 'recordingStarted' - Recording started
  • 'recordingStopped' - Recording stopped
  • 'checkpointCreated' - Checkpoint created
  • 'progress' - Progress update (duration)
  • 'error' - Error occurred
off(event: RecorderEventType, callback: EventListener<any>): void

Remove an event listener.

destroy(): void

Clean up resources and remove all listeners.

Enums and Types

RecorderState

enum RecorderState {
  IDLE = "idle",
  REQUESTING_PERMISSION = "requesting_permission",
  READY = "ready",
  RECORDING = "recording",
  PAUSED = "paused",
  STOPPED = "stopped",
  ERROR = "error",
}

AudioFormat

enum AudioFormat {
  WAV = "wav",
  PCM = "pcm",
}

SampleRate

enum SampleRate {
  SR_8000 = 8000,
  SR_11025 = 11025,
  SR_16000 = 16000,
  SR_22050 = 22050,
  SR_44100 = 44100,
  SR_48000 = 48000,
}

PermissionStatus

type PermissionStatus = "granted" | "denied" | "prompt" | "unknown";

React Example

import { useEffect, useState } from "react";
import {
  VoiceRecorder,
  RecorderState,
  AudioFormat,
  SampleRate,
  type RecordingResult,
} from "@superapp_men/voice-recorder-capacitor";

function VoiceRecorderComponent() {
  const [recorder] = useState(() => new VoiceRecorder({ debug: true }));
  const [state, setState] = useState<RecorderState>(RecorderState.IDLE);
  const [recording, setRecording] = useState<RecordingResult | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    // Listen to state changes
    const unsubscribe = recorder.on("stateChange", ({ state }) => {
      setState(state);
    });

    // Listen to errors
    const unsubError = recorder.on("error", ({ message }) => {
      setError(message);
    });

    return () => {
      unsubscribe();
      unsubError();
      recorder.destroy();
    };
  }, [recorder]);

  const handleStart = async () => {
    try {
      const permission = await recorder.requestPermission();
      if (permission !== "granted") {
        setError("Permission denied");
        return;
      }

      await recorder.startRecording({
        audioConfig: {
          format: AudioFormat.WAV,
          sampleRate: SampleRate.SR_16000,
          bitDepth: 16,
          channels: 1,
        },
      });
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to start");
    }
  };

  const handleStop = async () => {
    try {
      const result = await recorder.stopRecording();
      setRecording(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to stop");
    }
  };

  return (
    <div>
      <button
        onClick={handleStart}
        disabled={state === RecorderState.RECORDING}
      >
        Start Recording
      </button>
      <button onClick={handleStop} disabled={state !== RecorderState.RECORDING}>
        Stop Recording
      </button>

      {error && <div style={{ color: "red" }}>{error}</div>}

      {recording && (
        <audio controls src={`data:audio/wav;base64,${recording.audioData}`} />
      )}
    </div>
  );
}

Audio Format Support

Supported Formats

  • WAV - Waveform Audio File Format (recommended)
  • PCM - Raw Pulse Code Modulation

Recommended Configurations

Voice Recording (Low Bandwidth):

{
  format: AudioFormat.WAV,
  sampleRate: SampleRate.SR_16000,
  bitDepth: 16,
  channels: 1,
}

High Quality:

{
  format: AudioFormat.WAV,
  sampleRate: SampleRate.SR_44100,
  bitDepth: 16,
  channels: 2,
}

Checkpoint Mode

Checkpoint mode allows you to create intermediate audio segments during a single recording session. This is useful for:

  • Creating segments for transcription
  • Marking important sections
  • Allowing users to review segments before continuing
  • Creating structured audio data

When checkpoint mode is enabled:

  • Each checkpoint creates a segment of audio from the last checkpoint (or start)
  • The final recording result includes all segments merged into one complete audio file
  • Individual checkpoint segments are also available in the result

Error Handling

The package uses error events and throws exceptions for error conditions:

try {
  await recorder.startRecording();
} catch (error) {
  if (error instanceof Error) {
    console.error("Recording failed:", error.message);
  }
}

// Or use event listener
recorder.on("error", ({ message }) => {
  console.error("Error:", message);
});

Troubleshooting

Permission Issues

If you encounter permission errors:

  1. Ensure microphone permission is requested before starting
  2. Check that the SuperApp has properly configured microphone permissions
  3. Verify that permission requests are being handled by the SuperApp

Audio Not Playing

  • Ensure the audio data is properly base64-encoded
  • Use the correct MIME type: data:audio/wav;base64,${audioData}
  • Check browser/platform audio codec support

Checkpoint Mode Issues

  • Ensure isCheckpoints: true is set when starting recording
  • Check that all checkpoints have valid audio data
  • Verify the merged audio result in the final recording

Debug Mode

Enable debug mode for detailed logging:

const recorder = new VoiceRecorder({ debug: true });

This will log all operations, state changes, and API calls to the console.

Platform Support

This package is designed for partner apps running within a SuperApp environment. Full functionality is provided when:

  • The SuperApp has proper native audio recording support configured
  • Microphone permissions are properly handled by the SuperApp
  • The SuperApp implements the voice recorder message handlers

License

MIT

Support