/** * Per-provider connect timeout overrides from user settings. * Settings are read from the DB lazily and cached with a short TTL * so UI changes take effect without requiring a restart. */ let cached = {}; let cacheTs = 0; const CACHE_TTL_MS = 10_000; // 10s — responsive enough for dashboard changes async function refreshCache() { const now = Date.now(); if (now - cacheTs < CACHE_TTL_MS && Object.keys(cached).length > 0) return cached; try { const { getSettings } = await import("@/lib/localDb"); // Return full settings so we can read providerTimeouts + globalTimeoutMs cached = await getSettings(); cacheTs = now; } catch { // If DB is unavailable, keep stale cache — don't throw on hot path } return cached; } /** * Resolve the effective connect timeout for a provider. * Priority: per-provider override > global default timeout (settings) > registry config > env default. * @param {string} providerId * @param {number} configTimeoutMs - timeoutMs from the static provider registry config * @param {number} envDefaultMs - global default from env (FETCH_CONNECT_TIMEOUT_MS) * @returns {number} timeout in milliseconds */ export async function resolveProviderTimeoutMs(providerId, configTimeoutMs, envDefaultMs) { const overrides = await refreshCache(); // 1. Per-provider override (set in provider detail page) const providerOverride = overrides.providerTimeouts?.[providerId]; if (providerOverride?.timeoutMs && Number.isFinite(providerOverride.timeoutMs) && providerOverride.timeoutMs > 0) { return providerOverride.timeoutMs; } // 2. Global default timeout (set in Profile / Settings page) const globalDefault = overrides.defaultTimeoutMs; if (globalDefault && Number.isFinite(globalDefault) && globalDefault > 0) { return globalDefault; } // 3. Registry per-provider config if (configTimeoutMs && Number.isFinite(configTimeoutMs) && configTimeoutMs > 0) { return configTimeoutMs; } // 4. Env default return envDefaultMs; }