91 lines
3.9 KiB
TypeScript

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 { Translator } from '~/src/translator.ts';
const setDefault = async <K, V>(map: Map<K, V>, key: K, supplier: () => Promise<V>): Promise<V> => {
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<string, Config> = new Map();
export const loadConfig = async (locale: string): Promise<Config> => {
return setDefault(configByLocale, locale, async () => {
return loadSuml<Config>(`/locale/${locale}/config.suml`);
});
};
const baseTranslations = await loadSuml('locale/_base/translations.suml');
const translatorByLocale: Map<string, Translator> = new Map();
export const loadTranslator = async (locale: string): Promise<Translator> => {
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<string, Record<string, Pronoun>> = new Map();
export const loadPronouns = async (locale: string): Promise<Record<string, Pronoun>> => {
return setDefault(pronounsByLocale, locale, async () => {
const [config, pronounsRaw] = await Promise.all([
loadConfig(locale),
loadTsv<PronounData<string>>(`locale/${locale}/pronouns/pronouns.tsv`),
]);
return parsePronouns(config, pronounsRaw);
});
};
const pronounGroupsByLocale: Map<string, PronounGroup[]> = new Map();
export const loadPronounGroups = async (locale: string): Promise<PronounGroup[]> => {
return setDefault(pronounGroupsByLocale, locale, async () => {
return parsePronounGroups(await loadTsv(`locale/${locale}/pronouns/pronounGroups.tsv`));
});
};
const pronounLibraryByLocale: Map<string, PronounLibrary> = new Map();
export const loadPronounLibrary = async (locale: string): Promise<PronounLibrary> => {
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<string, PronounExamplesData[]> = new Map();
export const loadPronounExamples = async (locale: string): Promise<PronounExamplesData[]> => {
return setDefault(pronounExamplesByLocale, locale, async () => {
return loadTsv<PronounExamplesData>(`locale/${locale}/pronouns/examples.tsv`);
});
};
const calendarByLocale: Map<string, Calendar> = new Map();
export const loadCalendar = async (locale: string): Promise<Calendar> => {
return setDefault(calendarByLocale, locale, async () => {
const localeEventImports = (await import('#virtual/calendar/events.ts')).default;
const localEvents = await localeEventImports[locale]();
return buildCalendar(localEvents, getUrlForLocale(locale));
});
};