UNPKG

@hot-updater/react-native

Version:

React Native OTA solution for self-hosted

108 lines (99 loc) 3.9 kB
import type { TurboModule } from "react-native"; import { TurboModuleRegistry } from "react-native"; export interface UpdateBundleParams { bundleId: string; fileUrl: string | null; /** * File hash for integrity/signature verification. * * Format depends on signing configuration: * - Signed: `sig:<base64_signature>` - Native will verify signature (and implicitly hash) * - Unsigned: `<hex_hash>` - Native will verify SHA256 hash only * * Native determines verification mode by checking for "sig:" prefix. */ fileHash: string | null; } export interface Spec extends TurboModule { // Methods reload(): Promise<void>; /** * Downloads and applies a bundle update. * * @param params - Update bundle parameters * @returns Promise that resolves to true if successful * @throws {HotUpdaterErrorCode} Rejects with one of the following error codes: * * Parameter validation: * - MISSING_BUNDLE_ID: Missing or empty bundleId * - INVALID_FILE_URL: Invalid fileUrl provided * * Bundle storage: * - DIRECTORY_CREATION_FAILED: Failed to create bundle directory * - DOWNLOAD_FAILED: Failed to download bundle * - INCOMPLETE_DOWNLOAD: Download incomplete (size mismatch) * - EXTRACTION_FORMAT_ERROR: Invalid or corrupted archive format * - INVALID_BUNDLE: Bundle missing required platform files * - INSUFFICIENT_DISK_SPACE: Insufficient disk space * - MOVE_OPERATION_FAILED: Failed to move bundle files * - BUNDLE_IN_CRASHED_HISTORY: Bundle was previously marked as crashed * * Signature: * - SIGNATURE_VERIFICATION_FAILED: Any signature/hash verification failure * * Internal: * - SELF_DEALLOCATED: Native object was deallocated (iOS) * - UNKNOWN_ERROR: Fallback for rare or platform-specific errors * * Note: iOS normalizes rare signature/storage errors to SIGNATURE_VERIFICATION_FAILED * or UNKNOWN_ERROR to keep the JS error surface small. */ updateBundle(params: UpdateBundleParams): Promise<boolean>; /** * Notifies the native side that the app has successfully started with the given bundle. * If the bundle matches the staging bundle, it promotes to stable. * * @param params - Parameters containing the bundle ID * @returns Object with status and optional crashedBundleId * - `status: "PROMOTED"` - Staging bundle was promoted to stable (ACTIVE event) * - `status: "RECOVERED"` - App recovered from crash, rollback occurred (ROLLBACK event) * - `status: "STABLE"` - No changes, already stable * - `crashedBundleId` - Present only when status is "RECOVERED" */ notifyAppReady(params: { bundleId: string }): { status: "PROMOTED" | "RECOVERED" | "STABLE"; crashedBundleId?: string; }; /** * Gets the list of bundle IDs that have been marked as crashed. * These bundles will be rejected if attempted to install again. * * @returns Array of crashed bundle IDs */ getCrashHistory(): string[]; /** * Clears the crashed bundle history, allowing previously crashed bundles * to be installed again. * * @returns true if clearing was successful */ clearCrashHistory(): boolean; /** * Gets the base URL for the current active bundle directory. * Returns the file:// URL to the bundle directory without trailing slash. * This is used for Expo DOM components to construct full asset paths. * * @returns Base URL string (e.g., "file:///data/.../bundle-store/abc123") or "" if not available */ getBaseURL: () => string; // EventEmitter addListener(eventName: string): void; removeListeners(count: number): void; readonly getConstants: () => { MIN_BUNDLE_ID: string; APP_VERSION: string | null; CHANNEL: string; FINGERPRINT_HASH: string | null; }; } export default TurboModuleRegistry.getEnforcing<Spec>("HotUpdater");