import type { H3Event } from 'h3'; import type { Config } from '~/locale/config.ts'; import type { PronounData, PronounExamplesData } from '~/locale/data.ts'; import { loadSuml, loadTsv } from '~/server/loader.ts'; import { parsePronounGroups, parsePronouns } from '~/src/buildPronoun.ts'; import { buildCalendar } from '~/src/calendar/calendar.ts'; import type { Calendar } from '~/src/calendar/helpers.ts'; import { PronounLibrary } from '~/src/classes.ts'; import type { Pronoun, PronounGroup } from '~/src/classes.ts'; import { getLocaleForUrl, getUrlForLocale } from '~/src/domain.ts'; import type { NounsData } from '~/src/nouns.ts'; import { Translator } from '~/src/translator.ts'; const setDefault = async (map: Map, key: K, supplier: () => Promise): Promise => { const value = map.get(key); if (value !== undefined) { return value; } const computedValue = await supplier(); map.set(key, computedValue); return computedValue; }; export const getLocale = (event: H3Event): string => { const query = getQuery(event); if (typeof query.locale === 'string') { return query.locale; } return getLocaleForUrl(getRequestURL(event)) ?? '_'; }; const configByLocale: Map = new Map(); export const loadConfig = async (locale: string): Promise => { return setDefault(configByLocale, locale, async () => { return loadSuml(`/locale/${locale}/config.suml`); }); }; const baseTranslations = await loadSuml('locale/_base/translations.suml'); const translatorByLocale: Map = new Map(); export const loadTranslator = async (locale: string): Promise => { return setDefault(translatorByLocale, locale, async () => { const [config, translations] = await Promise.all([loadConfig(locale), loadSuml(`locale/${locale}/translations.suml`)]); return new Translator(translations, baseTranslations, config); }); }; const pronounsByLocale: Map> = new Map(); export const loadPronouns = async (locale: string): Promise> => { return setDefault(pronounsByLocale, locale, async () => { const [config, pronounsRaw] = await Promise.all([ loadConfig(locale), loadTsv>(`locale/${locale}/pronouns/pronouns.tsv`), ]); return parsePronouns(config, pronounsRaw); }); }; const pronounGroupsByLocale: Map = new Map(); export const loadPronounGroups = async (locale: string): Promise => { return setDefault(pronounGroupsByLocale, locale, async () => { return parsePronounGroups(await loadTsv(`locale/${locale}/pronouns/pronounGroups.tsv`)); }); }; const pronounLibraryByLocale: Map = new Map(); export const loadPronounLibrary = async (locale: string): Promise => { return setDefault(pronounLibraryByLocale, locale, async () => { const [config, pronounGroups, pronouns] = await Promise.all([loadConfig(locale), loadPronounGroups(locale), loadPronouns(locale)]); return new PronounLibrary(config, pronounGroups, pronouns); }); }; const pronounExamplesByLocale: Map = new Map(); export const loadPronounExamples = async (locale: string): Promise => { return setDefault(pronounExamplesByLocale, locale, async () => { return loadTsv(`locale/${locale}/pronouns/examples.tsv`); }); }; const nounsDataByLocale: Map = new Map(); export const loadNounsData = async (locale: string): Promise => { return setDefault(nounsDataByLocale, locale, async () => { return loadSuml(`locale/${locale}/nouns/nounsData.suml`); }); }; const calendarByLocale: Map = new Map(); export const loadCalendar = async (locale: string): Promise => { return setDefault(calendarByLocale, locale, async () => { const localeEventImports = (await import('#virtual/calendar/events.ts')).default; const localEvents = await localeEventImports[locale](); return buildCalendar(localEvents, getUrlForLocale(locale)); }); };