@bota-dev/react-native-sdk 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +279 -0
- package/lib/commonjs/BotaClient.js +223 -0
- package/lib/commonjs/BotaClient.js.map +1 -0
- package/lib/commonjs/ble/BleManager.js +494 -0
- package/lib/commonjs/ble/BleManager.js.map +1 -0
- package/lib/commonjs/ble/constants.js +166 -0
- package/lib/commonjs/ble/constants.js.map +1 -0
- package/lib/commonjs/ble/index.js +54 -0
- package/lib/commonjs/ble/index.js.map +1 -0
- package/lib/commonjs/ble/parsers.js +345 -0
- package/lib/commonjs/ble/parsers.js.map +1 -0
- package/lib/commonjs/index.js +81 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/managers/DeviceManager.js +437 -0
- package/lib/commonjs/managers/DeviceManager.js.map +1 -0
- package/lib/commonjs/managers/OTAManager.js +227 -0
- package/lib/commonjs/managers/OTAManager.js.map +1 -0
- package/lib/commonjs/managers/RecordingManager.js +384 -0
- package/lib/commonjs/managers/RecordingManager.js.map +1 -0
- package/lib/commonjs/managers/index.js +27 -0
- package/lib/commonjs/managers/index.js.map +1 -0
- package/lib/commonjs/models/Device.js +2 -0
- package/lib/commonjs/models/Device.js.map +1 -0
- package/lib/commonjs/models/Recording.js +2 -0
- package/lib/commonjs/models/Recording.js.map +1 -0
- package/lib/commonjs/models/Status.js +6 -0
- package/lib/commonjs/models/Status.js.map +1 -0
- package/lib/commonjs/models/index.js +39 -0
- package/lib/commonjs/models/index.js.map +1 -0
- package/lib/commonjs/protocol/ProtocolHandler.js +343 -0
- package/lib/commonjs/protocol/ProtocolHandler.js.map +1 -0
- package/lib/commonjs/protocol/index.js +13 -0
- package/lib/commonjs/protocol/index.js.map +1 -0
- package/lib/commonjs/storage/StorageManager.js +333 -0
- package/lib/commonjs/storage/StorageManager.js.map +1 -0
- package/lib/commonjs/storage/index.js +19 -0
- package/lib/commonjs/storage/index.js.map +1 -0
- package/lib/commonjs/upload/S3Uploader.js +133 -0
- package/lib/commonjs/upload/S3Uploader.js.map +1 -0
- package/lib/commonjs/upload/UploadQueue.js +280 -0
- package/lib/commonjs/upload/UploadQueue.js.map +1 -0
- package/lib/commonjs/upload/index.js +20 -0
- package/lib/commonjs/upload/index.js.map +1 -0
- package/lib/commonjs/utils/errors.js +187 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/index.js +40 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/logger.js +135 -0
- package/lib/commonjs/utils/logger.js.map +1 -0
- package/lib/commonjs/utils/retry.js +160 -0
- package/lib/commonjs/utils/retry.js.map +1 -0
- package/lib/module/BotaClient.js +216 -0
- package/lib/module/BotaClient.js.map +1 -0
- package/lib/module/ble/BleManager.js +484 -0
- package/lib/module/ble/BleManager.js.map +1 -0
- package/lib/module/ble/constants.js +159 -0
- package/lib/module/ble/constants.js.map +1 -0
- package/lib/module/ble/index.js +8 -0
- package/lib/module/ble/index.js.map +1 -0
- package/lib/module/ble/parsers.js +328 -0
- package/lib/module/ble/parsers.js.map +1 -0
- package/lib/module/index.js +22 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/managers/DeviceManager.js +429 -0
- package/lib/module/managers/DeviceManager.js.map +1 -0
- package/lib/module/managers/OTAManager.js +219 -0
- package/lib/module/managers/OTAManager.js.map +1 -0
- package/lib/module/managers/RecordingManager.js +376 -0
- package/lib/module/managers/RecordingManager.js.map +1 -0
- package/lib/module/managers/index.js +8 -0
- package/lib/module/managers/index.js.map +1 -0
- package/lib/module/models/Device.js +2 -0
- package/lib/module/models/Device.js.map +1 -0
- package/lib/module/models/Recording.js +2 -0
- package/lib/module/models/Recording.js.map +1 -0
- package/lib/module/models/Status.js +2 -0
- package/lib/module/models/Status.js.map +1 -0
- package/lib/module/models/index.js +8 -0
- package/lib/module/models/index.js.map +1 -0
- package/lib/module/protocol/ProtocolHandler.js +336 -0
- package/lib/module/protocol/ProtocolHandler.js.map +1 -0
- package/lib/module/protocol/index.js +6 -0
- package/lib/module/protocol/index.js.map +1 -0
- package/lib/module/storage/StorageManager.js +324 -0
- package/lib/module/storage/StorageManager.js.map +1 -0
- package/lib/module/storage/index.js +6 -0
- package/lib/module/storage/index.js.map +1 -0
- package/lib/module/upload/S3Uploader.js +126 -0
- package/lib/module/upload/S3Uploader.js.map +1 -0
- package/lib/module/upload/UploadQueue.js +272 -0
- package/lib/module/upload/UploadQueue.js.map +1 -0
- package/lib/module/upload/index.js +7 -0
- package/lib/module/upload/index.js.map +1 -0
- package/lib/module/utils/errors.js +173 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/index.js +8 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/logger.js +129 -0
- package/lib/module/utils/logger.js.map +1 -0
- package/lib/module/utils/retry.js +149 -0
- package/lib/module/utils/retry.js.map +1 -0
- package/lib/typescript/src/BotaClient.d.ts +77 -0
- package/lib/typescript/src/BotaClient.d.ts.map +1 -0
- package/lib/typescript/src/ble/BleManager.d.ts +111 -0
- package/lib/typescript/src/ble/BleManager.d.ts.map +1 -0
- package/lib/typescript/src/ble/constants.d.ts +111 -0
- package/lib/typescript/src/ble/constants.d.ts.map +1 -0
- package/lib/typescript/src/ble/index.d.ts +7 -0
- package/lib/typescript/src/ble/index.d.ts.map +1 -0
- package/lib/typescript/src/ble/parsers.d.ts +100 -0
- package/lib/typescript/src/ble/parsers.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/managers/DeviceManager.d.ts +84 -0
- package/lib/typescript/src/managers/DeviceManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/OTAManager.d.ts +78 -0
- package/lib/typescript/src/managers/OTAManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/RecordingManager.d.ts +90 -0
- package/lib/typescript/src/managers/RecordingManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/index.d.ts +7 -0
- package/lib/typescript/src/managers/index.d.ts.map +1 -0
- package/lib/typescript/src/models/Device.d.ts +139 -0
- package/lib/typescript/src/models/Device.d.ts.map +1 -0
- package/lib/typescript/src/models/Recording.d.ts +110 -0
- package/lib/typescript/src/models/Recording.d.ts.map +1 -0
- package/lib/typescript/src/models/Status.d.ts +104 -0
- package/lib/typescript/src/models/Status.d.ts.map +1 -0
- package/lib/typescript/src/models/index.d.ts +7 -0
- package/lib/typescript/src/models/index.d.ts.map +1 -0
- package/lib/typescript/src/protocol/ProtocolHandler.d.ts +69 -0
- package/lib/typescript/src/protocol/ProtocolHandler.d.ts.map +1 -0
- package/lib/typescript/src/protocol/index.d.ts +5 -0
- package/lib/typescript/src/protocol/index.d.ts.map +1 -0
- package/lib/typescript/src/storage/StorageManager.d.ts +116 -0
- package/lib/typescript/src/storage/StorageManager.d.ts.map +1 -0
- package/lib/typescript/src/storage/index.d.ts +5 -0
- package/lib/typescript/src/storage/index.d.ts.map +1 -0
- package/lib/typescript/src/upload/S3Uploader.d.ts +38 -0
- package/lib/typescript/src/upload/S3Uploader.d.ts.map +1 -0
- package/lib/typescript/src/upload/UploadQueue.d.ts +95 -0
- package/lib/typescript/src/upload/UploadQueue.d.ts.map +1 -0
- package/lib/typescript/src/upload/index.d.ts +6 -0
- package/lib/typescript/src/upload/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/errors.d.ts +82 -0
- package/lib/typescript/src/utils/errors.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +7 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/logger.d.ts +68 -0
- package/lib/typescript/src/utils/logger.d.ts.map +1 -0
- package/lib/typescript/src/utils/retry.d.ts +53 -0
- package/lib/typescript/src/utils/retry.d.ts.map +1 -0
- package/package.json +95 -0
- package/src/BotaClient.ts +238 -0
- package/src/ble/BleManager.ts +573 -0
- package/src/ble/constants.ts +158 -0
- package/src/ble/index.ts +7 -0
- package/src/ble/parsers.ts +395 -0
- package/src/index.ts +64 -0
- package/src/managers/DeviceManager.ts +545 -0
- package/src/managers/OTAManager.ts +263 -0
- package/src/managers/RecordingManager.ts +434 -0
- package/src/managers/index.ts +12 -0
- package/src/models/Device.ts +164 -0
- package/src/models/Recording.ts +123 -0
- package/src/models/Status.ts +126 -0
- package/src/models/index.ts +7 -0
- package/src/protocol/ProtocolHandler.ts +459 -0
- package/src/protocol/index.ts +5 -0
- package/src/storage/StorageManager.ts +343 -0
- package/src/storage/index.ts +5 -0
- package/src/upload/S3Uploader.ts +164 -0
- package/src/upload/UploadQueue.ts +310 -0
- package/src/upload/index.ts +6 -0
- package/src/utils/errors.ts +310 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/logger.ts +137 -0
- package/src/utils/retry.ts +177 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for the Bota SDK
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { LogLevel } from '../models/Status';
|
|
6
|
+
|
|
7
|
+
const LOG_LEVELS: Record<LogLevel, number> = {
|
|
8
|
+
debug: 0,
|
|
9
|
+
info: 1,
|
|
10
|
+
warn: 2,
|
|
11
|
+
error: 3,
|
|
12
|
+
none: 4,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Logger class with configurable log levels
|
|
17
|
+
*/
|
|
18
|
+
class Logger {
|
|
19
|
+
private level: LogLevel = 'warn';
|
|
20
|
+
private prefix = '[BotaSDK]';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Set the log level
|
|
24
|
+
*/
|
|
25
|
+
setLevel(level: LogLevel): void {
|
|
26
|
+
this.level = level;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get the current log level
|
|
31
|
+
*/
|
|
32
|
+
getLevel(): LogLevel {
|
|
33
|
+
return this.level;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if a log level should be output
|
|
38
|
+
*/
|
|
39
|
+
private shouldLog(level: LogLevel): boolean {
|
|
40
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Format a log message with optional context
|
|
45
|
+
*/
|
|
46
|
+
private format(
|
|
47
|
+
level: string,
|
|
48
|
+
message: string,
|
|
49
|
+
context?: Record<string, unknown>
|
|
50
|
+
): string {
|
|
51
|
+
const timestamp = new Date().toISOString();
|
|
52
|
+
const contextStr = context ? ` ${JSON.stringify(context)}` : '';
|
|
53
|
+
return `${timestamp} ${this.prefix} [${level.toUpperCase()}] ${message}${contextStr}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Log a debug message
|
|
58
|
+
*/
|
|
59
|
+
debug(message: string, context?: Record<string, unknown>): void {
|
|
60
|
+
if (this.shouldLog('debug')) {
|
|
61
|
+
console.debug(this.format('debug', message, context));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Log an info message
|
|
67
|
+
*/
|
|
68
|
+
info(message: string, context?: Record<string, unknown>): void {
|
|
69
|
+
if (this.shouldLog('info')) {
|
|
70
|
+
console.info(this.format('info', message, context));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Log a warning message
|
|
76
|
+
*/
|
|
77
|
+
warn(message: string, context?: Record<string, unknown>): void {
|
|
78
|
+
if (this.shouldLog('warn')) {
|
|
79
|
+
console.warn(this.format('warn', message, context));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Log an error message
|
|
85
|
+
*/
|
|
86
|
+
error(message: string, error?: Error, context?: Record<string, unknown>): void {
|
|
87
|
+
if (this.shouldLog('error')) {
|
|
88
|
+
const fullContext = error
|
|
89
|
+
? { ...context, error: error.message, stack: error.stack }
|
|
90
|
+
: context;
|
|
91
|
+
console.error(this.format('error', message, fullContext));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create a child logger with a specific tag
|
|
97
|
+
*/
|
|
98
|
+
tag(tag: string): TaggedLogger {
|
|
99
|
+
return new TaggedLogger(this, tag);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Tagged logger for component-specific logging
|
|
105
|
+
*/
|
|
106
|
+
class TaggedLogger {
|
|
107
|
+
constructor(
|
|
108
|
+
private parent: Logger,
|
|
109
|
+
private tag: string
|
|
110
|
+
) {}
|
|
111
|
+
|
|
112
|
+
debug(message: string, context?: Record<string, unknown>): void {
|
|
113
|
+
this.parent.debug(`[${this.tag}] ${message}`, context);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
info(message: string, context?: Record<string, unknown>): void {
|
|
117
|
+
this.parent.info(`[${this.tag}] ${message}`, context);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
warn(message: string, context?: Record<string, unknown>): void {
|
|
121
|
+
this.parent.warn(`[${this.tag}] ${message}`, context);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
error(message: string, error?: Error, context?: Record<string, unknown>): void {
|
|
125
|
+
this.parent.error(`[${this.tag}] ${message}`, error, context);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Singleton logger instance
|
|
131
|
+
*/
|
|
132
|
+
export const logger = new Logger();
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Export types for external use
|
|
136
|
+
*/
|
|
137
|
+
export type { TaggedLogger };
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry utility with exponential backoff
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { logger } from './logger';
|
|
6
|
+
|
|
7
|
+
const log = logger.tag('Retry');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Retry configuration options
|
|
11
|
+
*/
|
|
12
|
+
export interface RetryOptions {
|
|
13
|
+
/** Maximum number of retry attempts (default: 6) */
|
|
14
|
+
maxAttempts?: number;
|
|
15
|
+
/** Base delay in milliseconds (default: 1000) */
|
|
16
|
+
baseDelayMs?: number;
|
|
17
|
+
/** Maximum delay in milliseconds (default: 14400000 = 4 hours) */
|
|
18
|
+
maxDelayMs?: number;
|
|
19
|
+
/** Backoff multiplier (default: 2) */
|
|
20
|
+
backoffMultiplier?: number;
|
|
21
|
+
/** Add jitter to delays (default: true) */
|
|
22
|
+
jitter?: boolean;
|
|
23
|
+
/** Callback for each retry attempt */
|
|
24
|
+
onRetry?: (attempt: number, error: Error, delayMs: number) => void;
|
|
25
|
+
/** Predicate to determine if error is retryable (default: all errors) */
|
|
26
|
+
isRetryable?: (error: Error) => boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default retry delays based on Bota spec:
|
|
31
|
+
* Attempt 1: Immediate
|
|
32
|
+
* Attempt 2: 30 seconds
|
|
33
|
+
* Attempt 3: 2 minutes
|
|
34
|
+
* Attempt 4: 10 minutes
|
|
35
|
+
* Attempt 5: 1 hour
|
|
36
|
+
* Attempt 6: 4 hours
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_RETRY_DELAYS = [
|
|
39
|
+
0, // Immediate
|
|
40
|
+
30 * 1000, // 30 seconds
|
|
41
|
+
2 * 60 * 1000, // 2 minutes
|
|
42
|
+
10 * 60 * 1000, // 10 minutes
|
|
43
|
+
60 * 60 * 1000, // 1 hour
|
|
44
|
+
4 * 60 * 60 * 1000, // 4 hours
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Calculate delay for a retry attempt using exponential backoff
|
|
49
|
+
*/
|
|
50
|
+
export function calculateDelay(
|
|
51
|
+
attempt: number,
|
|
52
|
+
options: RetryOptions = {}
|
|
53
|
+
): number {
|
|
54
|
+
const {
|
|
55
|
+
baseDelayMs = 1000,
|
|
56
|
+
maxDelayMs = 14400000,
|
|
57
|
+
backoffMultiplier = 2,
|
|
58
|
+
jitter = true,
|
|
59
|
+
} = options;
|
|
60
|
+
|
|
61
|
+
// Use predefined delays for upload retries
|
|
62
|
+
if (attempt < DEFAULT_RETRY_DELAYS.length) {
|
|
63
|
+
const delay = DEFAULT_RETRY_DELAYS[attempt];
|
|
64
|
+
if (jitter && delay > 0) {
|
|
65
|
+
// Add up to 10% jitter
|
|
66
|
+
return delay + Math.random() * delay * 0.1;
|
|
67
|
+
}
|
|
68
|
+
return delay;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Fall back to exponential backoff for additional retries
|
|
72
|
+
let delay = baseDelayMs * Math.pow(backoffMultiplier, attempt);
|
|
73
|
+
delay = Math.min(delay, maxDelayMs);
|
|
74
|
+
|
|
75
|
+
if (jitter) {
|
|
76
|
+
// Add up to 10% jitter
|
|
77
|
+
delay = delay + Math.random() * delay * 0.1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return Math.floor(delay);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sleep for a specified duration
|
|
85
|
+
*/
|
|
86
|
+
export function sleep(ms: number): Promise<void> {
|
|
87
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Execute a function with retry logic
|
|
92
|
+
*/
|
|
93
|
+
export async function withRetry<T>(
|
|
94
|
+
fn: () => Promise<T>,
|
|
95
|
+
options: RetryOptions = {}
|
|
96
|
+
): Promise<T> {
|
|
97
|
+
const {
|
|
98
|
+
maxAttempts = 6,
|
|
99
|
+
onRetry,
|
|
100
|
+
isRetryable = () => true,
|
|
101
|
+
} = options;
|
|
102
|
+
|
|
103
|
+
let lastError: Error | undefined;
|
|
104
|
+
|
|
105
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
106
|
+
try {
|
|
107
|
+
return await fn();
|
|
108
|
+
} catch (error) {
|
|
109
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
110
|
+
|
|
111
|
+
// Check if error is retryable
|
|
112
|
+
if (!isRetryable(lastError)) {
|
|
113
|
+
log.debug('Error is not retryable, throwing immediately', {
|
|
114
|
+
attempt,
|
|
115
|
+
error: lastError.message,
|
|
116
|
+
});
|
|
117
|
+
throw lastError;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Check if we have more attempts
|
|
121
|
+
if (attempt >= maxAttempts - 1) {
|
|
122
|
+
log.warn('Max retry attempts reached', {
|
|
123
|
+
attempt: attempt + 1,
|
|
124
|
+
maxAttempts,
|
|
125
|
+
error: lastError.message,
|
|
126
|
+
});
|
|
127
|
+
throw lastError;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Calculate delay
|
|
131
|
+
const delayMs = calculateDelay(attempt, options);
|
|
132
|
+
|
|
133
|
+
log.debug('Retrying after error', {
|
|
134
|
+
attempt: attempt + 1,
|
|
135
|
+
maxAttempts,
|
|
136
|
+
delayMs,
|
|
137
|
+
error: lastError.message,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Notify callback
|
|
141
|
+
if (onRetry) {
|
|
142
|
+
onRetry(attempt + 1, lastError, delayMs);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Wait before retrying
|
|
146
|
+
if (delayMs > 0) {
|
|
147
|
+
await sleep(delayMs);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// This should never be reached, but TypeScript needs it
|
|
153
|
+
throw lastError ?? new Error('Retry failed');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Create a retryable wrapper for a function
|
|
158
|
+
*/
|
|
159
|
+
export function makeRetryable<T extends (...args: unknown[]) => Promise<unknown>>(
|
|
160
|
+
fn: T,
|
|
161
|
+
options: RetryOptions = {}
|
|
162
|
+
): T {
|
|
163
|
+
return (async (...args: Parameters<T>): Promise<ReturnType<T>> => {
|
|
164
|
+
return withRetry(() => fn(...args) as Promise<ReturnType<T>>, options);
|
|
165
|
+
}) as T;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Check if we should continue retrying based on total time elapsed
|
|
170
|
+
*/
|
|
171
|
+
export function shouldContinueRetrying(
|
|
172
|
+
startTime: Date,
|
|
173
|
+
maxDurationMs: number = 24 * 60 * 60 * 1000 // 24 hours
|
|
174
|
+
): boolean {
|
|
175
|
+
const elapsed = Date.now() - startTime.getTime();
|
|
176
|
+
return elapsed < maxDurationMs;
|
|
177
|
+
}
|