PronounsPage/shared/fetchJson.ts
2025-08-25 21:01:11 +02:00

55 lines
1.6 KiB
TypeScript

const cache = new Map<string, any>();
const inflight = new Map<string, Promise<any>>();
const doFetchJsonCached = async (locale: string, filename: string) => {
if (cache.has(filename)) { return cache.get(filename); }
if (inflight.has(filename)) { return inflight.get(filename)!; }
const p = (async () => {
const data = await $fetch(`/api/docs/${filename}`, { query: { locale } });
cache.set(filename, data);
inflight.delete(filename);
return data;
})().catch((err) => {
inflight.delete(filename);
throw err;
});
inflight.set(filename, p);
return p;
};
export const fetchJson = async (locale: string, filename: string, key: string) => {
let c = await doFetchJsonCached(locale, filename);
// terrible conventions, i know… i'm so tired…
let explicitSign = false;
let absolute = false;
if (key.startsWith('@')) {
explicitSign = true;
key = key.substring(1);
}
if (key.startsWith('^')) {
absolute = true;
key = key.substring(1);
}
for (let part of key.replace(/\\\./g, '£').split('.')) {
part = part.replace(/&#39;/g, '\'').replace(/£/g, '.');
c = c[part];
if (c === undefined) {
throw `item "${part}" is undefined (file ${filename})`;
}
}
if (typeof c === 'number') {
if (absolute) {
c = Math.abs(c);
}
if (explicitSign && c > 0) {
c = `+${c}`;
}
// TODO make generic
c = c.toString().replace('.', ',');
}
return c;
};