Skip to content

Commit 1be66e6

Browse files
authored
impr(language): check language integrity only once (@fehmer) (#7417)
1 parent 8ab345d commit 1be66e6

1 file changed

Lines changed: 37 additions & 37 deletions

File tree

frontend/src/ts/utils/json-data.ts

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,44 +35,39 @@ async function fetchJson<T>(url: string): Promise<T> {
3535

3636
/**
3737
* Memoizes an asynchronous function.
38-
* @template P The type of the function's parameters.
39-
* @template T The type of the function.
40-
* @param {T} fn The asynchronous function to memoize.
41-
* @param {(...args: Parameters<T>) => P} [getKey] Optional function to generate cache keys based on function arguments.
42-
* @returns {T} The memoized function.
38+
* @template P Cache key type
39+
* @template Args Function argument tuple
40+
* @template R Resolved value of the Promise
41+
* @param fn The async function to memoize.
42+
* @param getKey Optional function to compute a cache key from the function arguments. If omitted, the first argument is used as the key.
43+
* @returns A memoized version of the async function with the same signature.
4344
*/
44-
export function memoizeAsync<P, T extends <B>(...args: P[]) => Promise<B>>(
45-
fn: T,
46-
getKey?: (...args: Parameters<T>) => P,
47-
): T {
48-
const cache = new Map<P, Promise<ReturnType<T>>>();
49-
50-
return (async (...args: Parameters<T>): Promise<ReturnType<T>> => {
51-
const key = getKey ? getKey.apply(args) : (args[0] as P);
52-
53-
if (cache.has(key)) {
54-
const ret = await cache.get(key);
55-
if (ret !== undefined) {
56-
return ret as ReturnType<T>;
57-
}
45+
export function memoizeAsync<P, Args extends unknown[], R>(
46+
fn: (...args: Args) => Promise<R>,
47+
getKey?: (...args: Args) => P,
48+
): (...args: Args) => Promise<R> {
49+
const cache = new Map<P, Promise<R>>();
50+
51+
return async (...args: Args): Promise<R> => {
52+
const key = getKey ? getKey(...args) : (args[0] as P);
53+
54+
const cached = cache.get(key);
55+
if (cached) {
56+
return cached;
5857
}
5958

60-
// oxlint-disable-next-line prefer-spread
61-
const result = fn.apply(null, args) as Promise<ReturnType<T>>;
59+
const result = fn(...args);
6260
cache.set(key, result);
63-
6461
return result;
65-
}) as T;
62+
};
6663
}
6764

6865
/**
6966
* Memoizes the fetchJson function to cache the results of fetch requests.
7067
* @param url - The URL used to fetch JSON data.
7168
* @returns A promise that resolves to the cached JSON data.
7269
*/
73-
export const cachedFetchJson = memoizeAsync<string, typeof fetchJson>(
74-
fetchJson,
75-
);
70+
export const cachedFetchJson = memoizeAsync(fetchJson);
7671

7772
/**
7873
* Fetches a layout by name from the server.
@@ -92,17 +87,9 @@ export type LanguageProperties = Pick<
9287

9388
let currentLanguage: LanguageObject;
9489

95-
/**
96-
* Fetches the language object for a given language from the server.
97-
* @param lang The language code.
98-
* @returns A promise that resolves to the language object.
99-
*/
100-
export async function getLanguage(lang: Language): Promise<LanguageObject> {
101-
// try {
102-
if (currentLanguage === undefined || currentLanguage.name !== lang) {
103-
const loaded = await cachedFetchJson<LanguageObject>(
104-
`/languages/${lang}.json`,
105-
);
90+
const cachedFetchLanguage = memoizeAsync(
91+
async (lang: Language): Promise<LanguageObject> => {
92+
const loaded = await fetchJson<LanguageObject>(`/languages/${lang}.json`);
10693

10794
if (!isDevEnvironment()) {
10895
//check the content to make it less easy to manipulate
@@ -116,6 +103,19 @@ export async function getLanguage(lang: Language): Promise<LanguageObject> {
116103
);
117104
}
118105
}
106+
return loaded;
107+
},
108+
);
109+
/**
110+
* Fetches the language object for a given language from the server.
111+
* @param lang The language code.
112+
* @returns A promise that resolves to the language object.
113+
*/
114+
export async function getLanguage(lang: Language): Promise<LanguageObject> {
115+
// try {
116+
if (currentLanguage === undefined || currentLanguage.name !== lang) {
117+
const loaded = await cachedFetchLanguage(lang);
118+
119119
currentLanguage = loaded;
120120
}
121121
return currentLanguage;

0 commit comments

Comments
 (0)