mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-14 00:03:42 +08:00
- Bump version to 4.8.0 and update dependencies in package.json - Implement user config sync API for cross-device settings persistence - Add resolution badge auto-hide hook for improved user experience - Create useConfigSync hook to manage user settings synchronization with the server
73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
/**
|
|
* HTTP Utilities for API calls
|
|
* Handles timeouts and retries
|
|
*/
|
|
|
|
// Disable SSL verification for video sources with invalid certificates
|
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
|
|
const REQUEST_TIMEOUT = 15000;
|
|
const MAX_RETRIES = 3;
|
|
const RETRY_DELAY = 200;
|
|
|
|
/**
|
|
* Fetch with timeout support
|
|
* Accepts an optional external AbortSignal for cancellation cascade.
|
|
*/
|
|
export async function fetchWithTimeout(
|
|
url: string,
|
|
options: RequestInit = {},
|
|
timeout: number = REQUEST_TIMEOUT
|
|
): Promise<Response> {
|
|
const controller = new AbortController();
|
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
|
|
// If an external signal is provided, propagate its abort
|
|
const externalSignal = options.signal;
|
|
if (externalSignal) {
|
|
if (externalSignal.aborted) {
|
|
clearTimeout(timeoutId);
|
|
controller.abort();
|
|
} else {
|
|
const onAbort = () => controller.abort();
|
|
externalSignal.addEventListener('abort', onAbort, { once: true });
|
|
}
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
...options,
|
|
signal: controller.signal,
|
|
});
|
|
clearTimeout(timeoutId);
|
|
return response;
|
|
} catch (error) {
|
|
clearTimeout(timeoutId);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retry logic wrapper
|
|
*/
|
|
export async function withRetry<T>(
|
|
fn: () => Promise<T>,
|
|
retries: number = MAX_RETRIES
|
|
): Promise<T> {
|
|
let lastError: Error | null = null;
|
|
|
|
for (let i = 0; i <= retries; i++) {
|
|
try {
|
|
return await fn();
|
|
} catch (error) {
|
|
lastError = error as Error;
|
|
|
|
if (i < retries) {
|
|
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY * (i + 1)));
|
|
}
|
|
}
|
|
}
|
|
|
|
throw lastError;
|
|
}
|