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

hp-app-bundle-sdk

v1.0.6

Published

A comprehensive SDK for building mini-applications.

Readme

MiniApp SDK

A comprehensive TypeScript SDK for building native mobile mini-applications with modular architecture, native bridge communication, and extensive platform integration capabilities.

Introduction

The MiniApp SDK provides a unified interface for developing mini-applications that run within native mobile apps. It offers a modular architecture with dedicated managers for authentication, payments, UI components, storage, caching, and utility functions. The SDK handles native bridge communication, event management, and provides both modern module-based APIs and legacy compatibility.

Installation

# Using npm
npm install hp-app-bundle-sdk

# Using yarn
yarn add hp-app-bundle-sdk

Project Structure

The SDK follows a modular architecture with clear separation of concerns:

src/
├── core/                    # Core SDK functionality
│   ├── MiniApp.ts          # Main SDK class
│   ├── ConfigManager.ts    # Configuration management
│   ├── EventManager.ts     # Event system
│   ├── NativeBridge.ts     # Native communication
│   └── types.ts            # Core type definitions
├── modules/                 # Feature modules
│   ├── auth/               # Authentication module
│   ├── biometrics/         # Biometric authentication
│   ├── cache/              # Caching system
│   ├── contacts/           # Device contacts
│   ├── payment/            # Payment processing
│   ├── storage/            # Data storage
│   ├── ui/                 # UI components
│   └── utility/            # Utility functions
└── index.ts                # Main exports

Core Components

  • MiniApp: Main SDK class that orchestrates all modules and provides legacy compatibility
  • ConfigManager: Handles SDK configuration with deep merging and validation
  • EventManager: Type-safe event system for inter-module communication
  • NativeBridge: Manages communication between JavaScript and native platforms

Module Managers

  • AuthManager: Handles Firebase, Google, and Facebook authentication
  • BiometricsManager: Manages biometric authentication (TouchID, FaceID, fingerprint)
  • CacheManager: Provides in-memory and persistent caching with TTL and LRU eviction
  • ContactManager: Device contacts access with permission management
  • PaymentManager: Payment processing, verification, and history
  • StorageManager: Secure and standard storage with encryption support
  • UIManager: Native UI components (toasts, alerts, loading indicators)
  • UtilityManager: Utility functions (QR codes, file downloads, sharing, calling)

Complete Method Reference

AuthManager

Handles user authentication with multiple providers including Firebase, Google, and Facebook.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | login(provider?) | provider?: 'google' \| 'facebook' \| 'firebase' | Promise<UserProfile> | Authenticate user with specified provider (default: firebase) | | logout() | None | Promise<void> | Log out current user and clear tokens | | getAccessToken() | None | Promise<string> | Get current access token | | isAuthenticated() | None | Promise<boolean> | Check if user is authenticated | | getUserProfile() | None | Promise<UserProfile> | Get current user profile | | firebaseSignOut() | None | Promise<void> | Sign out from Firebase | | initializeFirebase(config) | config: FirebaseAuthConfig | void | Initialize Firebase with config |

UIManager

Provides native UI components and interactions with web fallbacks.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | showToast(message, options?) | message: string, options?: ToastOptions | Promise<void> | Show toast notification | | showAlert(message, options?) | message: string, options?: AlertOptions | Promise<void> | Show alert dialog | | showConfirm(message, options?) | message: string, options?: ConfirmOptions | Promise<boolean> | Show confirmation dialog | | showActionSheet(options) | options: ActionSheetOptions | Promise<string \| null> | Show action sheet with options | | showLoading(options?) | options?: LoadingOptions | Promise<void> | Show loading indicator | | hideLoading() | None | Promise<void> | Hide loading indicator | | setTitle(title) | title: string | Promise<void> | Set navigation bar title | | setNavigationBarColor(color, textColor?) | color: string, textColor?: 'light' \| 'dark' | Promise<void> | Set navigation bar color |

PaymentManager

Handles payment processing, verification, and history with auto-verification support.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | makePayment(request) | request: PaymentRequest | Promise<PaymentResult> | Process payment with auto-verification | | verifyPayment(referenceId) | referenceId: string | Promise<PaymentResult> | Verify payment by reference ID | | getPaymentHistory(options?) | options?: { limit?: number, offset?: number } | Promise<PaymentResult[]> | Get payment history with pagination |

ContactManager

Manages device contacts with comprehensive permission handling.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | checkPermission() | None | Promise<ContactsPermissionResult> | Check current permission status | | requestPermission() | None | Promise<ContactsPermissionResult> | Request contacts permission | | getContacts(options?) | options?: { limit?: number, offset?: number } | Promise<Contact[]> | Get device contacts with pagination | | searchContacts(query, options?) | query: string, options?: { limit?: number } | Promise<Contact[]> | Search contacts by query | | getContact(contactId) | contactId: string | Promise<Contact \| null> | Get specific contact by ID |

BiometricsManager

Handles biometric authentication (TouchID, FaceID, Fingerprint).

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | isAvailable() | None | Promise<boolean> | Check if biometrics are available | | getBiometryType() | None | Promise<'TouchID' \| 'FaceID' \| 'Fingerprint' \| 'None'> | Get available biometry type | | authenticate(reason?) | reason?: string | Promise<BiometricResult> | Authenticate with biometrics |

StorageManager

Provides secure and standard storage with encryption support.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | setItem(key, value) | key: string, value: any | Promise<void> | Store data with optional encryption | | getItem<T>(key) | key: string | Promise<T \| null> | Retrieve and decrypt data | | removeItem(key) | key: string | Promise<void> | Remove stored item | | clear() | None | Promise<void> | Clear all stored data | | getAllKeys() | None | Promise<string[]> | Get all storage keys |

CacheManager

Intelligent caching with TTL, LRU eviction, and size management.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | set<T>(key, value, ttl?) | key: string, value: T, ttl?: number | Promise<void> | Cache data with optional TTL | | get<T>(key) | key: string | Promise<T \| undefined> | Retrieve cached data | | delete(key) | key: string | Promise<boolean> | Remove cached item | | clear() | None | Promise<void> | Clear all cached data | | has(key) | key: string | Promise<boolean> | Check if key exists in cache | | getStats() | None | { hits: number, misses: number, totalSize: number } | Get cache statistics | | cleanup() | None | Promise<void> | Remove expired items |

UtilityManager

Utility functions for QR codes, downloads, sharing, and calling with timeout support.

| Method | Parameters | Return Value | Description | |--------|------------|--------------|-------------| | showQR(qrData, productType) | qrData: string, productType: string | Promise<any> | Display QR code with timeout | | downloadFile(url, fileType, productType) | url: string, fileType: string, productType: string | Promise<any> | Download file with timeout | | share(content, imageUrl?) | content: string, imageUrl?: string | Promise<any> | Share content with timeout | | call(payload, productType, credentials, meetingId) | payload: string, productType: string, credentials: string, meetingId: string | Promise<any> | Make call with timeout |

Usage Guide

Basic Setup

import { MiniApp } from 'hp-app-bundle-sdk';

// Initialize with optional configuration
const miniapp = new MiniApp({
    core: {
        logLevel: 'info',
        enableAnalytics: true,
        autoInitialize: false
    }
});

// Initialize with client ID
await miniapp.init('your-client-id');

Using Multiple Modules Simultaneously

Example 1: Secure Payment Flow with Biometric Authentication

const miniapp = new MiniApp();
await miniapp.init('your-client-id');

// Initialize modules
const auth = miniapp.useAuth({ autoRefresh: true });
const biometrics = miniapp.useBiometrics({ allowDeviceCredentials: true });
const payment = miniapp.usePayment({ autoVerify: true });
const ui = miniapp.useUI();
const storage = miniapp.useStorage({ defaultStorage: 'secure', encrypt: true });

async function processSecurePayment(amount: number, description: string) {
    try {
        // 1. Check if user is authenticated
        const isAuth = await auth.isAuthenticated();
        if (!isAuth) {
            await ui.showAlert('Please login first');
            const user = await auth.login('firebase');
            await ui.showToast(`Welcome, ${user.name}!`);
        }

        // 2. Verify biometric authentication for high-value transactions
        if (amount > 1000) {
            const biometricAvailable = await biometrics.isAvailable();
            if (biometricAvailable) {
                const biometricResult = await biometrics.authenticate(
                    `Authenticate payment of $${amount}`
                );

                if (!biometricResult.success) {
                    await ui.showAlert('Biometric authentication required for this transaction');
                    return;
                }
            }
        }

        // 3. Show loading and process payment
        await ui.showLoading({ text: 'Processing payment...', cancelable: false });

        const paymentResult = await payment.makePayment({
            amount: amount * 100, // Convert to cents
            currency: 'USD',
            description,
            referenceId: `txn_${Date.now()}`
        });

        await ui.hideLoading();

        // 4. Handle payment result
        if (paymentResult.success) {
            // Store transaction for offline access
            await storage.setItem(`transaction_${paymentResult.transactionId}`, {
                ...paymentResult,
                timestamp: new Date().toISOString()
            });

            await ui.showToast('Payment successful!');
            return paymentResult;
        } else {
            await ui.showAlert('Payment failed. Please try again.');
        }

    } catch (error) {
        await ui.hideLoading();
        await ui.showAlert(`Error: ${error.message}`);
    }
}

// Usage
await processSecurePayment(1500, 'Premium subscription');

Example 2: Contact Sharing with Caching and UI Feedback

const miniapp = new MiniApp();
await miniapp.init('your-client-id');

// Initialize modules
const contacts = miniapp.useContacts();
const cache = miniapp.useCache({ maxSize: 5 * 1024 * 1024, defaultTTL: 3600000 });
const ui = miniapp.useUI();
const utility = miniapp.useUtility({ timeout: 30000 });

async function shareContactList() {
    try {
        // 1. Check cache first
        let contactList = await cache.get('device_contacts');

        if (!contactList) {
            // 2. Request permission with user feedback
            await ui.showLoading({ text: 'Requesting contacts permission...' });

            const permission = await contacts.requestPermission();
            await ui.hideLoading();

            if (!permission.granted) {
                const retry = await ui.showConfirm(
                    'Contacts permission is required to share your contact list. Would you like to try again?'
                );

                if (retry && permission.canAskAgain) {
                    return await shareContactList(); // Retry
                } else {
                    await ui.showAlert('Cannot share contacts without permission');
                    return;
                }
            }

            // 3. Fetch contacts with progress feedback
            await ui.showLoading({ text: 'Loading contacts...' });
            contactList = await contacts.getContacts({ limit: 500 });
            await ui.hideLoading();

            // 4. Cache the results
            await cache.set('device_contacts', contactList);
            await ui.showToast(`Loaded ${contactList.length} contacts`);
        } else {
            await ui.showToast(`Using cached contacts (${contactList.length} items)`);
        }

        // 5. Let user select sharing method
        const shareMethod = await ui.showActionSheet({
            title: 'How would you like to share?',
            options: ['Share as Text', 'Generate QR Code', 'Send via Email'],
            cancelText: 'Cancel'
        });

        if (!shareMethod || shareMethod === 'Cancel') return;

        // 6. Process based on selection
        const contactText = contactList.map(c => `${c.name}: ${c.phoneNumbers?.[0]}`).join('\n');

        switch (shareMethod) {
            case 'Share as Text':
                await utility.share(contactText);
                break;

            case 'Generate QR Code':
                await utility.showQR(JSON.stringify(contactList), 'contacts');
                break;

            case 'Send via Email':
                await utility.share(
                    `My Contacts:\n\n${contactText}`,
                    undefined // No image
                );
                break;
        }

        await ui.showToast('Contacts shared successfully!');

    } catch (error) {
        await ui.hideLoading();
        await ui.showAlert(`Failed to share contacts: ${error.message}`);
    }
}

// Usage
await shareContactList();

Example 3: Multi-Module Data Sync with Event Handling

const miniapp = new MiniApp();
await miniapp.init('your-client-id');

// Initialize all modules
const auth = miniapp.useAuth({ autoRefresh: true });
const storage = miniapp.useStorage({ defaultStorage: 'secure', encrypt: true });
const cache = miniapp.useCache({ storageType: 'localStorage', defaultTTL: 1800000 });
const ui = miniapp.useUI();
const payment = miniapp.usePayment();

// Set up event listeners for cross-module communication
miniapp.events.on('auth:login:success', async (event) => {
    const user = event.data;

    // Cache user profile
    await cache.set('current_user', user, 3600000); // 1 hour

    // Load user preferences from storage
    const preferences = await storage.getItem('user_preferences');
    if (preferences) {
        await ui.showToast(`Welcome back, ${user.name}!`);
    } else {
        await ui.showToast(`Welcome, ${user.name}! Setting up your profile...`);
        // Set default preferences
        await storage.setItem('user_preferences', {
            theme: 'light',
            notifications: true,
            autoSync: true
        });
    }
});

miniapp.events.on('payment:completed', async (event) => {
    const paymentResult = event.data;

    if (paymentResult.success) {
        // Update user's payment history in cache
        const existingHistory = await cache.get('payment_history') || [];
        existingHistory.unshift(paymentResult);
        await cache.set('payment_history', existingHistory.slice(0, 10)); // Keep last 10

        // Store in secure storage for persistence
        await storage.setItem(`payment_${paymentResult.transactionId}`, paymentResult);

        await ui.showToast('Payment recorded successfully!');
    }
});

miniapp.events.on('storage:error', async (event) => {
    console.error('Storage error:', event.error);
    await ui.showAlert('Data sync failed. Please try again.');
});

// Main application flow
async function initializeApp() {
    try {
        await ui.showLoading({ text: 'Initializing app...' });

        // Check for cached user session
        const cachedUser = await cache.get('current_user');

        if (cachedUser && await auth.isAuthenticated()) {
            await ui.showToast(`Welcome back, ${cachedUser.name}!`);
        } else {
            // Prompt for login
            const shouldLogin = await ui.showConfirm('Would you like to sign in?');
            if (shouldLogin) {
                await auth.login('firebase');
            }
        }

        // Load cached payment history
        const paymentHistory = await cache.get('payment_history');
        if (paymentHistory?.length > 0) {
            console.log(`Loaded ${paymentHistory.length} recent payments`);
        }

        await ui.hideLoading();
        await ui.showToast('App ready!');

    } catch (error) {
        await ui.hideLoading();
        await ui.showAlert(`Initialization failed: ${error.message}`);
    }
}

// Start the app
await initializeApp();

Example 4: Offline-First Architecture with Multiple Modules

const miniapp = new MiniApp();
await miniapp.init('your-client-id');

// Initialize modules for offline-first approach
const storage = miniapp.useStorage({ defaultStorage: 'localStorage', encrypt: false });
const cache = miniapp.useCache({ storageType: 'localStorage', maxSize: 10 * 1024 * 1024 });
const ui = miniapp.useUI();
const auth = miniapp.useAuth({ tokenStorage: 'localStorage' });

class OfflineDataManager {
    constructor(private miniapp: MiniApp) {}

    async syncData() {
        const ui = this.miniapp.useUI();
        const storage = this.miniapp.useStorage({ defaultStorage: 'localStorage' });
        const cache = this.miniapp.useCache({ storageType: 'localStorage' });

        try {
            await ui.showLoading({ text: 'Syncing data...' });

            // Get pending offline actions
            const pendingActions = await storage.getItem('pending_actions') || [];

            if (pendingActions.length > 0) {
                for (const action of pendingActions) {
                    try {
                        await this.processAction(action);
                        // Remove successful action
                        const updatedActions = pendingActions.filter(a => a.id !== action.id);
                        await storage.setItem('pending_actions', updatedActions);
                    } catch (error) {
                        console.error(`Failed to sync action ${action.id}:`, error);
                    }
                }
            }

            // Update cache with fresh data
            await this.refreshCache();

            await ui.hideLoading();
            await ui.showToast('Data synced successfully!');

        } catch (error) {
            await ui.hideLoading();
            await ui.showAlert(`Sync failed: ${error.message}`);
        }
    }

    async addOfflineAction(action: any) {
        const storage = this.miniapp.useStorage({ defaultStorage: 'localStorage' });
        const pendingActions = await storage.getItem('pending_actions') || [];

        pendingActions.push({
            ...action,
            id: `action_${Date.now()}`,
            timestamp: new Date().toISOString()
        });

        await storage.setItem('pending_actions', pendingActions);
    }

    private async processAction(action: any) {
        // Process different types of offline actions
        switch (action.type) {
            case 'payment':
                const payment = this.miniapp.usePayment();
                return await payment.makePayment(action.data);

            case 'contact_update':
                const contacts = this.miniapp.useContacts();
                return await contacts.getContacts(); // Refresh contacts

            default:
                throw new Error(`Unknown action type: ${action.type}`);
        }
    }

    private async refreshCache() {
        const cache = this.miniapp.useCache({ storageType: 'localStorage' });

        // Clear expired items
        await cache.cleanup();

        // Refresh critical data
        const auth = this.miniapp.useAuth();
        if (await auth.isAuthenticated()) {
            const userProfile = await auth.getUserProfile();
            await cache.set('user_profile', userProfile, 3600000); // 1 hour
        }
    }
}

// Usage
const dataManager = new OfflineDataManager(miniapp);

// Sync data when app starts
await dataManager.syncData();

// Add offline actions when network is unavailable
await dataManager.addOfflineAction({
    type: 'payment',
    data: { amount: 5000, currency: 'USD', description: 'Offline payment' }
});

Event-Driven Architecture

// Set up comprehensive event handling across all modules
const miniapp = new MiniApp();
await miniapp.init('your-client-id');

// Global error handler
miniapp.events.on('*:error', async (event) => {
    console.error('Module error:', event);
    const ui = miniapp.useUI();
    await ui.showToast('An error occurred. Please try again.');
});

// Authentication events
miniapp.events.on('auth:login:success', (event) => {
    console.log('User logged in:', event.data.email);
});

miniapp.events.on('auth:logout:success', () => {
    console.log('User logged out');
    // Clear sensitive data
    const cache = miniapp.useCache({ storageType: 'memory' });
    cache.clear();
});

// Payment events
miniapp.events.on('payment:completed', (event) => {
    if (event.data.success) {
        console.log('Payment successful:', event.data.transactionId);
    }
});

// UI events
miniapp.events.on('ui:showToast:success', (event) => {
    console.log('Toast shown:', event.data);
});

// Storage events
miniapp.events.on('storage:set', (event) => {
    console.log('Data stored:', event.data.key);
});

// Utility events
miniapp.events.on('utility:share:success', () => {
    console.log('Content shared successfully');
});

Module Configuration Examples

// Configure modules with specific settings
const miniapp = new MiniApp({
    core: {
        logLevel: 'debug',
        enableAnalytics: true
    }
});

// Auth with multiple providers
const auth = miniapp.useAuth({
    autoRefresh: true,
    refreshInterval: 300000, // 5 minutes
    tokenStorage: 'localStorage',
    providers: {
        firebase: {
            apiKey: 'your-api-key',
            authDomain: 'your-domain.firebaseapp.com'
        },
        google: {
            clientId: 'your-google-client-id'
        }
    }
});

// UI with custom settings
const ui = miniapp.useUI({
    toastDuration: 5000,
    alertTitle: 'MyApp',
    confirmTitle: 'Confirm Action',
    loadingText: 'Please wait...'
});

// Payment with auto-verification
const payment = miniapp.usePayment({
    defaultCurrency: 'USD',
    autoVerify: true
});

// Storage with encryption
const storage = miniapp.useStorage({
    defaultStorage: 'secure',
    encrypt: true,
    keyPrefix: 'myapp_'
});

// Cache with size limits
const cache = miniapp.useCache({
    maxSize: 50 * 1024 * 1024, // 50MB
    defaultTTL: 1800000, // 30 minutes
    storageType: 'localStorage'
});

// Biometrics with fallback
const biometrics = miniapp.useBiometrics({
    allowDeviceCredentials: true,
    promptMessage: 'Authenticate to continue',
    cancelButtonText: 'Cancel',
    fallbackButtonText: 'Use Password'
});

// Contacts with auto-permission
const contacts = miniapp.useContacts({
    requestPermissionOnInit: true
});

// Utility with custom timeout
const utility = miniapp.useUtility({
    timeout: 45000 // 45 seconds
});