feat: cache marka api responses
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { createCache } from "../cache.ts";
|
||||
import { MARKA_API_KEY } from "../env.ts";
|
||||
import { getImage } from "../image.ts";
|
||||
import { GenericResource } from "./schema.ts";
|
||||
@@ -24,32 +25,62 @@ async function addImageToResource<T extends GenericResource>(
|
||||
return resource as T;
|
||||
}
|
||||
|
||||
export async function fetchResource<T extends GenericResource>(
|
||||
type Resource = GenericResource & {
|
||||
content: GenericResource["content"] & Array<GenericResource>;
|
||||
};
|
||||
|
||||
const fetchCache = createCache<Resource>("marka");
|
||||
const cacheLock = new Map<string, Promise<Resource>>();
|
||||
async function cachedFetch(
|
||||
url: string,
|
||||
): Promise<Resource | undefined> {
|
||||
if (fetchCache.has(url)) {
|
||||
return fetchCache.get(url);
|
||||
}
|
||||
if (cacheLock.has(url)) {
|
||||
return cacheLock.get(url);
|
||||
}
|
||||
const response = (async () => {
|
||||
const response = await fetch(url);
|
||||
const res = await response.json();
|
||||
fetchCache.set(url, res);
|
||||
return res;
|
||||
})();
|
||||
cacheLock.set(
|
||||
url,
|
||||
response,
|
||||
);
|
||||
const res = await response;
|
||||
if (!res) {
|
||||
cacheLock.delete(url);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function fetchResource<T extends Resource>(
|
||||
resource: string,
|
||||
): Promise<T | undefined> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url}/resources/${resource}`,
|
||||
);
|
||||
const res = await response.json();
|
||||
const d = `${url}/resources/${resource}`;
|
||||
const res = await cachedFetch(d);
|
||||
if (!res) return;
|
||||
return addImageToResource<T>(res);
|
||||
} catch (_e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export async function listResources<T = GenericResource>(
|
||||
export async function listResources<T extends GenericResource>(
|
||||
resource: string,
|
||||
): Promise<T[]> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url}/resources/${resource}`,
|
||||
);
|
||||
const list = await response.json();
|
||||
const d = `${url}/resources/${resource}`;
|
||||
const list = await cachedFetch(d);
|
||||
if (!list) return [];
|
||||
return Promise.all(
|
||||
list?.content
|
||||
.filter((a: GenericResource) => a?.content?._type)
|
||||
.map((res: GenericResource) => addImageToResource(res)),
|
||||
.filter((a) => a?.content?._type)
|
||||
.map((res) => addImageToResource(res) as Promise<T>),
|
||||
);
|
||||
} catch (_e) {
|
||||
return [];
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
export function formatDate(date: Date): string {
|
||||
export function formatDate(date?: string | Date): string {
|
||||
if (!date) return "";
|
||||
if (typeof date === "string") {
|
||||
try {
|
||||
const d = new Date(date);
|
||||
return formatDate(d);
|
||||
} catch (_e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
const options = { year: "numeric", month: "long", day: "numeric" } as const;
|
||||
return new Intl.DateTimeFormat("en-US", options).format(date);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user