UNPKG

react-native-healthkit-bridge

Version:

A comprehensive React Native bridge for Apple HealthKit with TypeScript support, advanced authorization, and flexible data queries

98 lines (97 loc) 3.56 kB
import { HEALTHKIT_CONFIG } from '../config/healthkit.config'; export class RetryManager { constructor() { this.defaultConfig = { maxAttempts: HEALTHKIT_CONFIG.MAX_RETRIES, baseDelay: HEALTHKIT_CONFIG.RETRY_DELAY, maxDelay: 10000, // 10 seconds backoffMultiplier: 2, retryableErrors: [ 'ERR_QUERY', 'ERR_NETWORK', 'ERR_TIMEOUT', 'ERR_HEALTHKIT_UNAVAILABLE' ] }; } static getInstance() { if (!RetryManager.instance) { RetryManager.instance = new RetryManager(); } return RetryManager.instance; } async withRetry(operation, config) { const finalConfig = Object.assign(Object.assign({}, this.defaultConfig), config); const startTime = Date.now(); let lastError; for (let attempt = 1; attempt <= finalConfig.maxAttempts; attempt++) { try { const data = await operation(); return { success: true, data, attempts: attempt, totalTime: Date.now() - startTime }; } catch (error) { lastError = error; // Check if error is retryable if (!this.isRetryableError(error, finalConfig.retryableErrors)) { return { success: false, error, attempts: attempt, totalTime: Date.now() - startTime }; } // If this is the last attempt, don't wait if (attempt === finalConfig.maxAttempts) { break; } // Calculate delay with exponential backoff const delay = Math.min(finalConfig.baseDelay * Math.pow(finalConfig.backoffMultiplier, attempt - 1), finalConfig.maxDelay); await this.sleep(delay); } } return { success: false, error: lastError, attempts: finalConfig.maxAttempts, totalTime: Date.now() - startTime }; } isRetryableError(error, retryableErrors) { if (!retryableErrors || retryableErrors.length === 0) { return true; // Retry all errors by default } const errorCode = (error === null || error === void 0 ? void 0 : error.code) || (error === null || error === void 0 ? void 0 : error.message) || ''; return retryableErrors.some(retryableError => errorCode.includes(retryableError)); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // Helper method for common retry scenarios async retryQuery(operation) { const result = await this.withRetry(operation, { retryableErrors: ['ERR_QUERY', 'ERR_TIMEOUT'] }); if (!result.success) { throw result.error; } return result.data; } async retryAuth(operation) { const result = await this.withRetry(operation, { retryableErrors: ['ERR_AUTHORIZATION', 'ERR_HEALTHKIT_UNAVAILABLE'] }); if (!result.success) { throw result.error; } return result.data; } } // Convenience function export function withRetry(operation, config) { return RetryManager.getInstance().withRetry(operation, config); }