Skip to content

Commit 43bf1d1

Browse files
Refactor metadata caching to use generic types and improve locale support
1 parent 8704460 commit 43bf1d1

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

apps/nextjs-website/src/helpers/s3Metadata.helpers.ts

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -205,55 +205,53 @@ const S3_SOAP_API_METADATA_JSON_PATH =
205205
process.env.S3_SOAP_API_METADATA_JSON_PATH ||
206206
'soap-api/soap-api-metadata.json';
207207

208-
type JsonMetadataCacheItem = {
208+
type MetadataCacheItem<T> = {
209209
readonly category: string;
210210
readonly locale: string;
211-
readonly jsonMetadata: readonly JsonMetadata[] | null;
211+
readonly data: readonly T[] | null;
212212
readonly refreshTime: number;
213213
};
214214

215-
type SoapApiJsonMetadataCacheItem = Pick<
216-
JsonMetadataCacheItem,
217-
'locale' | 'refreshTime'
218-
> & { readonly soapApiMetadata: readonly SoapApiJsonMetadata[] | null };
219-
220-
let jsonMetadataCache: readonly JsonMetadataCacheItem[] = [];
221-
let soapApiMetadataCache: readonly SoapApiJsonMetadataCacheItem[] = [];
215+
let metadataCache: readonly MetadataCacheItem<Record<string, unknown>>[] = [];
222216

223217
const METADATA_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
224218

225-
async function fetchJsonMetadataWithCache(
219+
async function fetchMetadataWithCache<T extends { readonly dirName: string }>(
226220
locale: string,
227221
metadataCategory: string,
228-
fetchFunction: () => Promise<readonly JsonMetadata[] | null>,
222+
fetchFunction: () => Promise<readonly T[] | null>,
229223
dirName?: string
230-
) {
224+
): Promise<MetadataCacheItem<T>> {
231225
const now = Date.now();
232-
const cacheResult = jsonMetadataCache.find(
233-
(item) =>
234-
item.category === metadataCategory &&
235-
item.locale === locale &&
236-
item.jsonMetadata &&
237-
now - item.refreshTime < METADATA_CACHE_TTL &&
238-
(!dirName || item.jsonMetadata.some((m) => m.dirName === dirName))
239-
);
226+
const cacheResult = metadataCache.find((item) => {
227+
const categoryMatch =
228+
item.category === metadataCategory && item.locale === locale;
229+
const timeMatch = item.data && now - item.refreshTime < METADATA_CACHE_TTL;
230+
const dirNameMatch =
231+
!dirName ||
232+
(Array.isArray(item.data) &&
233+
item.data.length > 0 &&
234+
'dirName' in item.data[0] &&
235+
item.data.some((m: Record<string, unknown>) => m.dirName === dirName));
236+
return categoryMatch && timeMatch && dirNameMatch;
237+
}) as MetadataCacheItem<T> | undefined;
240238

241239
if (cacheResult) {
242240
return cacheResult;
243241
}
244242

245243
const fetchMetadataResult = await fetchFunction();
246244

247-
const newCacheItem: JsonMetadataCacheItem = {
245+
const newCacheItem: MetadataCacheItem<T> = {
248246
category: metadataCategory,
249247
locale,
250-
jsonMetadata: fetchMetadataResult,
248+
data: fetchMetadataResult,
251249
refreshTime: now,
252250
};
253251

254-
jsonMetadataCache = [
255-
...jsonMetadataCache.filter(
256-
(item) => item.category === metadataCategory && item.locale !== locale
252+
metadataCache = [
253+
...metadataCache.filter(
254+
(item) => item.category !== metadataCategory || item.locale !== locale
257255
),
258256
newCacheItem,
259257
];
@@ -265,14 +263,14 @@ export const getGuidesMetadata = async (locale: string, dirName?: string) => {
265263
const fetchFromCdnPath = dirName
266264
? path.join(locale, S3_PATH_TO_GITBOOK_DOCS, dirName, S3_METADATA_JSON_PATH)
267265
: `${locale}/${S3_GUIDES_METADATA_JSON_PATH}`;
268-
const cacheResult = await fetchJsonMetadataWithCache(
266+
const cacheResult = await fetchMetadataWithCache<JsonMetadata>(
269267
locale,
270268
'guides',
271269
() => fetchMetadataFromCDN<JsonMetadata>(fetchFromCdnPath),
272270
dirName
273271
);
274272

275-
return cacheResult.jsonMetadata || [];
273+
return cacheResult.data || [];
276274
};
277275

278276
const removeTrailingSlash = (value: string) => value.replace(/\/+$/, '');
@@ -355,14 +353,14 @@ export const getSolutionsMetadata = async (
355353
? path.join(locale, S3_PATH_TO_GITBOOK_DOCS, dirName, S3_METADATA_JSON_PATH)
356354
: `${locale}/${S3_SOLUTIONS_METADATA_JSON_PATH}`;
357355

358-
const cacheResult = await fetchJsonMetadataWithCache(
356+
const cacheResult = await fetchMetadataWithCache<JsonMetadata>(
359357
locale,
360358
'solutions',
361359
() => fetchMetadataFromCDN<JsonMetadata>(fetchFromCdnPath),
362360
dirName
363361
);
364362

365-
return cacheResult.jsonMetadata || [];
363+
return cacheResult.data || [];
366364
};
367365

368366
export const getReleaseNotesMetadataByDirNames = async (
@@ -388,24 +386,25 @@ export const getReleaseNotesMetadata = async (
388386
? path.join(locale, S3_PATH_TO_GITBOOK_DOCS, dirName, S3_METADATA_JSON_PATH)
389387
: `${locale}/${S3_RELEASE_NOTES_METADATA_JSON_PATH}`;
390388

391-
const cacheResult = await fetchJsonMetadataWithCache(
389+
const cacheResult = await fetchMetadataWithCache<JsonMetadata>(
392390
locale,
393391
'releaseNotes',
394392
() => fetchMetadataFromCDN<JsonMetadata>(fetchFromCdnPath),
395393
dirName
396394
);
397395

398-
return cacheResult.jsonMetadata || [];
396+
return cacheResult.data || [];
399397
};
400398

401399
export const getSoapApiMetadata = async (locale: string) => {
402-
// if (soapApiMetadataCache) {
403-
// soapApiMetadataCache = await fetchMetadataFromCDN<SoapApiJsonMetadata>(
404-
// `${locale}/${S3_SOAP_API_METADATA_JSON_PATH}`
405-
// );
406-
// }
407-
// return soapApiMetadataCache || [];
408-
return fetchMetadataFromCDN<SoapApiJsonMetadata>(
409-
`${locale}/${S3_SOAP_API_METADATA_JSON_PATH}`
410-
).then((result) => result || []);
400+
const cacheResult = await fetchMetadataWithCache<SoapApiJsonMetadata>(
401+
locale,
402+
'soapApi',
403+
() =>
404+
fetchMetadataFromCDN<SoapApiJsonMetadata>(
405+
`${locale}/${S3_SOAP_API_METADATA_JSON_PATH}`
406+
)
407+
);
408+
409+
return cacheResult.data || [];
411410
};

0 commit comments

Comments
 (0)