diff --git a/api/resolvers/price.js b/api/resolvers/price.js index c04e7df9b..38f0c3c33 100644 --- a/api/resolvers/price.js +++ b/api/resolvers/price.js @@ -7,30 +7,36 @@ async function fetchPrice (fiat) { .then((res) => res.json()) .then((body) => parseFloat(body.data.amount)) .catch((err) => { - console.error(err) + console.error('price', err) return -1 }) cache.set(fiat, { price, createdAt: Date.now() }) return price } -async function getPrice (fiat) { +async function getPrice (fiat, fromCache = true) { fiat ??= 'USD' + + if (!fromCache) { + const newPrice = await fetchPrice(fiat) + return newPrice + } + if (cache.has(fiat)) { const { price, createdAt } = cache.get(fiat) const expired = createdAt + expiresIn < Date.now() - if (expired) fetchPrice(fiat).catch(console.error) // update cache + if (expired) fetchPrice(fiat).catch(console.error) return price // serve stale price (this on the SSR critical path) } else { fetchPrice(fiat).catch(console.error) + return null } - return null } export default { Query: { - price: async (parent, { fiatCurrency }, ctx) => { - return await getPrice(fiatCurrency) + price: async (parent, { fiatCurrency, fromCache }, ctx) => { + return await getPrice(fiatCurrency, fromCache) } } } diff --git a/api/typeDefs/price.js b/api/typeDefs/price.js index 5ffb8e367..1cd9e4ae2 100644 --- a/api/typeDefs/price.js +++ b/api/typeDefs/price.js @@ -2,6 +2,6 @@ import { gql } from 'graphql-tag' export default gql` extend type Query { - price(fiatCurrency: String): Float + price(fiatCurrency: String, fromCache: Boolean = true): Float } ` diff --git a/components/price.js b/components/price.js index 366aa3076..297f5426a 100644 --- a/components/price.js +++ b/components/price.js @@ -21,7 +21,7 @@ export function usePrice () { export function PriceProvider ({ price, children }) { const me = useMe() const fiatCurrency = me?.privates?.fiatCurrency - const { data } = useQuery(PRICE, { + const { data, refetch } = useQuery(PRICE, { variables: { fiatCurrency }, ...(SSR ? {} @@ -31,6 +31,11 @@ export function PriceProvider ({ price, children }) { }) }) + useEffect(() => { + if (fiatCurrency) { + refetch({ fiatCurrency, fromCache: false }) + } + }, [fiatCurrency, refetch]) const contextValue = useMemo(() => ({ price: data?.price || price, fiatSymbol: CURRENCY_SYMBOLS[fiatCurrency] || '$' diff --git a/fragments/price.js b/fragments/price.js index 39a18a83e..32bc396f8 100644 --- a/fragments/price.js +++ b/fragments/price.js @@ -1,6 +1,6 @@ import { gql } from '@apollo/client' export const PRICE = gql` - query price($fiatCurrency: String) { - price(fiatCurrency: $fiatCurrency) + query price($fiatCurrency: String, $fromCache: Boolean) { + price(fiatCurrency: $fiatCurrency, fromCache: $fromCache) }`