/** * Short-TTL in-process cache for the plugin-settings singleton. * * Settings are read on virtually every payment operation (create-order reads * them several times) but change only on an explicit admin save. A short TTL * removes the per-request DB round-trips while keeping multi-instance * deployments acceptably fresh: another instance picks a change up within the * TTL, and the instance that wrote it invalidates immediately. * * `PAYPAL_SETTINGS_CACHE_MS` overrides the TTL; `0` disables caching. */ export const SETTINGS_CACHE_TTL_MS = (() => { const v = Number(process.env.PAYPAL_SETTINGS_CACHE_MS) return Number.isFinite(v) && v >= 0 ? v : 15_000 })() type Slot = { value: unknown; at: number } const slots = new Map() export function getCachedSettings(key: string): T | null { if (SETTINGS_CACHE_TTL_MS <= 0) return null const slot = slots.get(key) if (!slot) return null if (Date.now() - slot.at >= SETTINGS_CACHE_TTL_MS) { slots.delete(key) return null } return slot.value as T } export function setCachedSettings(key: string, value: unknown): void { if (SETTINGS_CACHE_TTL_MS <= 0) return slots.set(key, { value, at: Date.now() }) } /** * Drop every cached settings view (module service AND credential resolver — * they cache different shapes of the same row). Called after a settings write * so reads in this process are immediately fresh. */ export function invalidateSettingsCache(): void { slots.clear() }