From 5b2bf56aee79c509b05cd9ab1f582adcc82faf64 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Thu, 2 Mar 2023 20:17:47 +0000 Subject: [PATCH] feat: cacheGet options --- src/lib/redis.server.ts | 24 ++++++------- src/pages/api/host2handle.ts | 69 +++++++++++++++++++----------------- src/pages/api/nfts.ts | 10 +++--- src/pages/api/slug2id.ts | 10 +++--- src/queries/page.server.ts | 24 ++++++++----- src/queries/site.server.ts | 25 ++++++++++--- 6 files changed, 94 insertions(+), 68 deletions(-) diff --git a/src/lib/redis.server.ts b/src/lib/redis.server.ts index a76e3d28..bb0e48c3 100644 --- a/src/lib/redis.server.ts +++ b/src/lib/redis.server.ts @@ -26,39 +26,39 @@ let redisPromise: Promise = new Promise((resolve, reject) => { export const getRedis = () => redisPromise -export async function cacheGet( - key: string | (Record | string | undefined)[], - getValueFun: () => Promise, - noUpdate?: boolean, -) { +export async function cacheGet(options: { + key: string | (Record | string | undefined)[] + getValueFun: () => Promise + noUpdate?: boolean +}) { const redis = await redisPromise if (redis && redis.status === "ready") { let redisKey: string - if (Array.isArray(key)) { - redisKey = key + if (Array.isArray(options.key)) { + redisKey = options.key .map((k) => (typeof k === "string" ? k : JSON.stringify(k))) .join(":") } else { - redisKey = key + redisKey = options.key } const cacheValue = await redis.get(redisKey) if (cacheValue) { - if (!noUpdate) { + if (!options.noUpdate) { setTimeout(() => { - getValueFun().then((value) => { + options.getValueFun().then((value) => { redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE) }) }, Math.random() * REDIS_REFRESH) } return JSON.parse(cacheValue) } else { - const value = await getValueFun() + const value = await options.getValueFun() redis.set(redisKey, JSON.stringify(value), "EX", REDIS_EXPIRE) return value } } else { console.error("redis not ready") - return await getValueFun() + return await options.getValueFun() } } diff --git a/src/pages/api/host2handle.ts b/src/pages/api/host2handle.ts index bf556567..776fd8e5 100644 --- a/src/pages/api/host2handle.ts +++ b/src/pages/api/host2handle.ts @@ -18,44 +18,47 @@ export default async function handler( const OUR_DOMAIN_SUFFIX = `.${OUR_DOMAIN}` if (realHost && realHost !== OUR_DOMAIN) { - result = await cacheGet(["host2handle", realHost], async () => { - if (realHost.endsWith(OUR_DOMAIN_SUFFIX)) { - const subdomain = realHost.replace(OUR_DOMAIN_SUFFIX, "") - const res = await fetch( - `https://indexer.crossbell.io/v1/handles/${subdomain}/character`, - ) - const char = await res.json() - const customDomain = - char?.metadata?.content?.attributes?.find( - (a: any) => a.trait_type === "xlog_custom_domain", - )?.value || "" - if (customDomain) { - return { - redirect: /^https?:\/\//.test(customDomain) - ? customDomain - : `https://${customDomain}`, - subdomain: subdomain, + result = await cacheGet({ + key: ["host2handle", realHost], + getValueFun: async () => { + if (realHost.endsWith(OUR_DOMAIN_SUFFIX)) { + const subdomain = realHost.replace(OUR_DOMAIN_SUFFIX, "") + const res = await fetch( + `https://indexer.crossbell.io/v1/handles/${subdomain}/character`, + ) + const char = await res.json() + const customDomain = + char?.metadata?.content?.attributes?.find( + (a: any) => a.trait_type === "xlog_custom_domain", + )?.value || "" + if (customDomain) { + return { + redirect: /^https?:\/\//.test(customDomain) + ? customDomain + : `https://${customDomain}`, + subdomain: subdomain, + } + } else { + return { + subdomain: subdomain, + } } } else { + const res = await fetch( + `https://cloudflare-dns.com/dns-query?name=_xlog-challenge.${realHost}&type=TXT`, + { + headers: { + accept: "application/dns-json", + }, + }, + ) + const txt = await res.json() + const tenant = txt?.Answer?.[0]?.data.replace(/^"|"$/g, "") return { - subdomain: subdomain, + subdomain: tenant, } } - } else { - const res = await fetch( - `https://cloudflare-dns.com/dns-query?name=_xlog-challenge.${realHost}&type=TXT`, - { - headers: { - accept: "application/dns-json", - }, - }, - ) - const txt = await res.json() - const tenant = txt?.Answer?.[0]?.data.replace(/^"|"$/g, "") - return { - subdomain: tenant, - } - } + }, }) } diff --git a/src/pages/api/nfts.ts b/src/pages/api/nfts.ts index 52a9d10f..b832cc5f 100644 --- a/src/pages/api/nfts.ts +++ b/src/pages/api/nfts.ts @@ -15,7 +15,7 @@ export default async function handler( return } - const redis = getRedis() + const redis = await getRedis() const redisKey = `nfts/${query.address}` let cache @@ -30,9 +30,9 @@ export default async function handler( result.list.map(async (nft: Asset) => { if (!nft.items?.[0].mime_type && nft.items?.[0]?.address) { try { - const mime_type = await cacheGet( - `nft-mimetype/${nft.items[0].address}`, - async () => { + const mime_type = await cacheGet({ + key: `nft-mimetype/${nft.items[0].address}`, + getValueFun: async () => { const head = await fetch( `${nft.items![0].address!.replace( IPFS_GATEWAY, @@ -44,7 +44,7 @@ export default async function handler( ) return head.headers.get("content-type") }, - ) + }) nft.items[0].mime_type = mime_type } catch (error) { console.warn(error) diff --git a/src/pages/api/slug2id.ts b/src/pages/api/slug2id.ts index 4c91a688..f9dcb744 100644 --- a/src/pages/api/slug2id.ts +++ b/src/pages/api/slug2id.ts @@ -6,9 +6,9 @@ import { getNoteSlug } from "~/lib/helpers" export async function getIdBySlug(slug: string, handle: string) { slug = (slug as string)?.toLowerCase?.() - const result = await cacheGet( - ["slug2id", handle, slug], - async () => { + const result = await cacheGet({ + key: ["slug2id", handle, slug], + getValueFun: async () => { let note let cursor = "" @@ -47,8 +47,8 @@ export async function getIdBySlug(slug: string, handle: string) { } } }, - true, - ) + noUpdate: true, + }) // revalidate if (result) { diff --git a/src/queries/page.server.ts b/src/queries/page.server.ts index 4c1ad4af..354d282d 100644 --- a/src/queries/page.server.ts +++ b/src/queries/page.server.ts @@ -20,7 +20,10 @@ export const fetchGetPage = async ( input.pageId = `${slug2Id.characterId}-${slug2Id.noteId}` } delete input.page - return cacheGet(key, () => pageModel.getPage(input)) + return cacheGet({ + key, + getValueFun: () => pageModel.getPage(input), + }) }) } @@ -32,12 +35,14 @@ export const prefetchGetPagesBySite = async ( await queryClient.prefetchInfiniteQuery({ queryKey: key, queryFn: async ({ pageParam }) => { - return cacheGet(key, () => - pageModel.getPagesBySite({ - ...input, - cursor: pageParam, - }), - ) + return cacheGet({ + key, + getValueFun: () => + pageModel.getPagesBySite({ + ...input, + cursor: pageParam, + }), + }) }, getNextPageParam: (lastPage) => lastPage.cursor || undefined, }) @@ -49,6 +54,9 @@ export const fetchGetPagesBySite = async ( ) => { const key = ["getPagesBySite", input.site, input] return await queryClient.fetchQuery(key, async () => { - return cacheGet(key, () => pageModel.getPagesBySite(input)) + return cacheGet({ + key, + getValueFun: () => pageModel.getPagesBySite(input), + }) }) } diff --git a/src/queries/site.server.ts b/src/queries/site.server.ts index 256bdc1d..86b6873d 100644 --- a/src/queries/site.server.ts +++ b/src/queries/site.server.ts @@ -8,14 +8,20 @@ export const prefetchGetSite = async ( ) => { const key = ["getSite", input] await queryClient.prefetchQuery(key, async () => { - return cacheGet(key, () => siteModel.getSite(input)) + return cacheGet({ + key, + getValueFun: () => siteModel.getSite(input), + }) }) } export const fetchGetSite = async (input: string, queryClient: QueryClient) => { const key = ["getSite", input] return await queryClient.fetchQuery(key, async () => { - return cacheGet(key, () => siteModel.getSite(input)) + return cacheGet({ + key, + getValueFun: () => siteModel.getSite(input), + }) }) } @@ -25,7 +31,10 @@ export const prefetchGetSiteSubscriptions = async ( ) => { const key = ["getSiteSubscriptions", input] await queryClient.prefetchQuery(key, async () => { - return cacheGet(key, () => siteModel.getSiteSubscriptions(input)) + return cacheGet({ + key, + getValueFun: () => siteModel.getSiteSubscriptions(input), + }) }) } @@ -35,7 +44,10 @@ export const prefetchGetSiteToSubscriptions = async ( ) => { const key = ["getSiteToSubscriptions", input] await queryClient.prefetchQuery(key, async () => { - return cacheGet(key, () => siteModel.getSiteToSubscriptions(input)) + return cacheGet({ + key, + getValueFun: () => siteModel.getSiteToSubscriptions(input), + }) }) } @@ -45,6 +57,9 @@ export const prefetchGetSites = async ( ) => { const key = ["getSites", input] await queryClient.fetchQuery(key, async () => { - return cacheGet(key, () => siteModel.getSites(input)) + return cacheGet({ + key, + getValueFun: () => siteModel.getSites(input), + }) }) }