/** * Process-wide cache for `Intl.NumberFormat` / `Intl.DateTimeFormat` * instances, keyed by locale + options. * * Constructing an `Intl.*` formatter is comparatively expensive; several * list-item helpers built one per row per render (`workout-list`, * `recent-workouts-tile`, `medication-card`, …). These getters return a cached * instance so the construction cost is paid once per distinct (locale, options) * shape instead of once per call. Formatters are immutable + stateless, so * sharing a single instance across calls is safe. * * Keyed by `locale + "" + JSON.stringify(options)`; stringifying the * (tiny, literal) options object per call is orders of magnitude cheaper than * a formatter construction. The set of distinct shapes is bounded and small, * so the cache never needs eviction. */ const numberFormatters = new Map(); const dateTimeFormatters = new Map(); export function getNumberFormat( locale: string, options: Intl.NumberFormatOptions, ): Intl.NumberFormat { const key = `${locale}${JSON.stringify(options)}`; let fmt = numberFormatters.get(key); if (!fmt) { fmt = new Intl.NumberFormat(locale, options); numberFormatters.set(key, fmt); } return fmt; } export function getDateTimeFormat( locale: string, options: Intl.DateTimeFormatOptions, ): Intl.DateTimeFormat { const key = `${locale}${JSON.stringify(options)}`; let fmt = dateTimeFormatters.get(key); if (!fmt) { fmt = new Intl.DateTimeFormat(locale, options); dateTimeFormatters.set(key, fmt); } return fmt; }