import { NitroModules } from 'react-native-nitro-modules'; import type { NativeDfuNitro, DfuOptions } from './specs/NativeDfuNitro.nitro'; import { DfuState, DfuError } from './specs/NativeDfuNitro.nitro'; // ─── Public Types ──────────────────────────────────────────────────────────── export interface DfuProgress { part: number; totalParts: number; progress: number; currentSpeed: number; avgSpeed: number; } export interface DfuManagerOptions extends DfuOptions { onStateChange?: (state: DfuState) => void; onProgress?: (progress: DfuProgress) => void; } export class DfuException extends Error { public readonly code: DfuError; constructor(code: DfuError, message: string) { super(message); this.name = 'DfuException'; this.code = code; } } // ─── Manager ───────────────────────────────────────────────────────────────── export class DfuNitroManager { private readonly native: NativeDfuNitro; constructor() { this.native = NitroModules.createHybridObject('NativeDfuNitro'); } /** * Start a DFU process. Returns a Promise that resolves when the DFU * completes successfully, or rejects with a `DfuException` on error/abort. * * Use `onStateChange` and `onProgress` in options to receive live updates. */ startDfu(options: DfuManagerOptions): Promise { const { onStateChange, onProgress, ...nativeOptions } = options; return new Promise((resolve, reject) => { this.native.startDfu( nativeOptions, (state) => { onStateChange?.(state); if (state === DfuState.Completed) { resolve(); } else if (state === DfuState.Aborted) { reject( new DfuException(DfuError.DeviceDisconnected, 'DFU was aborted'), ); } }, (part, totalParts, progress, currentSpeed, avgSpeed) => { onProgress?.({ part, totalParts, progress, currentSpeed, avgSpeed }); }, (error, message) => { reject(new DfuException(error, message)); }, ); }); } /** Pause the current DFU process. */ pause(): void { this.native.pauseDfu(); } /** Resume a paused DFU process. */ resume(): void { this.native.resumeDfu(); } /** Abort the current DFU process. */ abort(): void { this.native.abortDfu(); } }