@hot-updater/react-native
Version:
React Native OTA solution for self-hosted
108 lines (99 loc) • 3.9 kB
text/typescript
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");