From a01a242acd9da0784dd8801d62f6756577082f19 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:21:04 +0000 Subject: [PATCH] perf(storage): replace Promise.all map with single range query for fetchHistoricalRatesBatch Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> --- src/storage.ts | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/storage.ts b/src/storage.ts index 9544485..577911a 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -218,13 +218,50 @@ export async function fetchHistoricalRatesBatch(dates: string[]): Promise>>("fetch_historical_rates_batch", { dates }); } + const uniqueDates = Array.from(new Set(dates)); const results: Record> = {}; - await Promise.all( - dates.map(async (date) => { - const rates = await fetchHistoricalRates(date); - if (rates) results[date] = rates; - }) - ); + + if (uniqueDates.length === 0) return results; + + if (uniqueDates.length === 1) { + const rates = await fetchHistoricalRates(uniqueDates[0]!); + if (rates) results[uniqueDates[0]!] = rates; + return results; + } + + const minDate = uniqueDates.reduce((a, b) => (a < b ? a : b)); + const maxDate = uniqueDates.reduce((a, b) => (a > b ? a : b)); + + const res = await fetch(`https://api.frankfurter.dev/v1/${minDate}..${maxDate}?from=USD`); + const json = await res.json(); + + if (json?.rates) { + const availableDates = Object.keys(json.rates).sort(); + for (const reqDate of uniqueDates) { + let matchDate: string | undefined = undefined; + for (let i = 0; i < availableDates.length; i++) { + if (availableDates[i]! <= reqDate) matchDate = availableDates[i]; + else break; + } + + // In case there is a date requested prior to the first available date + // Frankfurter might not return a rate, fallback to individual query + if (!matchDate) { + const rates = await fetchHistoricalRates(reqDate); + if (rates) results[reqDate] = rates; + continue; + } + + const rates = json.rates[matchDate]; + if (rates) { + const out: Record = { USD: 1 }; + for (const [k, v] of Object.entries(rates as Record)) { + if (v > 0) out[k.toUpperCase()] = v; + } + results[reqDate] = out; + } + } + } return results; } catch (e) { console.warn("fetchHistoricalRatesBatch failed", e);