import { formatters } from '@adalo/constants' import { type DefaultOpts, getDateTimeStringFromISODateOnly, getNow, } from './datetime' import { relativeDate, relativeShort, absoluteDatetime, absoluteDate, universalDate, dayOfWeek, dayNumber, monthName, monthNumber, yearNumber, timeOnly, isoDateTime, isoDateOnly, } from './index' const CACHE_TTL = 5000 // 5 seconds export type Format = { type: string } type CacheValue = { value: string cached: number } const formatDateCache = new Map() export const formatDate = ( dateString: string, format: Format, options: DefaultOpts = {} ) => { const { type } = format const nowValue = getNow().valueOf() const key = JSON.stringify({ dateString, format }) if (formatDateCache.has(key)) { const cached = formatDateCache.get(key) as CacheValue if ( type === formatters.date.RELATIVE || type === formatters.date.RELATIVE_SHORT ) { if (nowValue - cached.cached < CACHE_TTL) { return cached.value } else { formatDateCache.delete(key) } } else { return cached.value } } const f = () => { try { switch (type) { case formatters.date.RELATIVE: return relativeDate(dateString, options) case formatters.date.RELATIVE_SHORT: return relativeShort(dateString, options) case formatters.date.ABSOLUTE_DATE: return absoluteDate(dateString, options) case formatters.date.UNIVERSAL_DATE: return universalDate(dateString, options) case formatters.date.ABSOLUTE_DATETIME: return absoluteDatetime(dateString, options) case formatters.date.WEEK_DAY_LONG: return dayOfWeek(dateString, false, options) case formatters.date.WEEK_DAY_SHORT: return dayOfWeek(dateString, true, options) case formatters.date.DAY_NUMBER: return dayNumber(dateString, options) case formatters.date.MONTH_NAME_LONG: return monthName(dateString, false, options) case formatters.date.MONTH_NAME_SHORT: return monthName(dateString, true, options) case formatters.date.MONTH_NUMBER: return monthNumber(dateString, options) case formatters.date.YEAR_NUMBER_LONG: return yearNumber(dateString, false, options) case formatters.date.YEAR_NUMBER_SHORT: return yearNumber(dateString, true, options) case formatters.date.TIME: return timeOnly(dateString, options) case formatters.date.ISO: default: return isoDateTime(dateString, options) } } catch { return dateString } } const formattedDate = f() formatDateCache.set(key, { value: formattedDate, cached: nowValue, }) return formattedDate } const formatDateOnlyCache = new Map() export const formatDateOnly = ( dateString: string, format: Format, options: DefaultOpts = {} ) => { const { type } = format const nowValue = getNow().valueOf() const key = JSON.stringify({ dateString, format }) if (formatDateOnlyCache.has(key)) { const cached = formatDateOnlyCache.get(key) as CacheValue if (type === formatters.dateOnly.RELATIVE) { if (nowValue - cached.cached < CACHE_TTL) { return cached.value } else { formatDateOnlyCache.delete(key) } } else { return cached.value } } const f = () => { try { const dateTime = getDateTimeStringFromISODateOnly(dateString) switch (type) { case formatters.dateOnly.RELATIVE: return relativeDate(dateTime, options) case formatters.dateOnly.ABSOLUTE_DATE: return absoluteDate(dateTime, options) case formatters.dateOnly.UNIVERSAL_DATE: return universalDate(dateTime, options) case formatters.dateOnly.WEEK_DAY_LONG: return dayOfWeek(dateTime, false, options) case formatters.dateOnly.WEEK_DAY_SHORT: return dayOfWeek(dateTime, true, options) case formatters.dateOnly.DAY_NUMBER: return dayNumber(dateTime, options) case formatters.dateOnly.MONTH_NAME_LONG: return monthName(dateTime, false, options) case formatters.dateOnly.MONTH_NAME_SHORT: return monthName(dateTime, true, options) case formatters.dateOnly.MONTH_NUMBER: return monthNumber(dateTime, options) case formatters.dateOnly.YEAR_NUMBER_LONG: return yearNumber(dateTime, false, options) case formatters.dateOnly.YEAR_NUMBER_SHORT: return yearNumber(dateTime, true, options) case formatters.dateOnly.ISO: default: return isoDateOnly(dateString, options) } } catch { return dateString } } const formattedDate = f() formatDateOnlyCache.set(key, { value: formattedDate, cached: nowValue, }) return formattedDate }