Skip to content

Instantly share code, notes, and snippets.

@guendev
Last active March 26, 2025 09:24
Show Gist options
  • Save guendev/4709b7be4b2f9196fe3d2505e1262ede to your computer and use it in GitHub Desktop.
Save guendev/4709b7be4b2f9196fe3d2505e1262ede to your computer and use it in GitHub Desktop.
import { isDefined } from 'remeda'
import type { KeyFields } from '@/cache/utils/generate-cache-key'
import type { JsonParsed } from '@/utils'
import { Cache } from '@/cache'
import { generateCacheKey } from '@/cache/utils/generate-cache-key'
interface UseCachedOptions<T> {
parser?: (raw: JsonParsed<NonNullable<T>>) => NonNullable<T>
resolver?: () => Promise<T>
ttl?: number
}
interface UseCachedOptionsWithDefault<T> extends UseCachedOptions<T> {
defaultValue: NonNullable<T>
}
export function useCached<T>(keyFields: KeyFields | string, options?: UseCachedOptions<T>): Promise<T>
export function useCached<T>(keyFields: KeyFields | string, options: UseCachedOptionsWithDefault<T>): Promise<T>
export async function useCached<T>(keyFields: KeyFields | string, options?: Partial<UseCachedOptionsWithDefault<T>>) {
const { client } = Cache.getInstance()
const { defaultValue, parser, resolver, ttl } = options || {}
const cacheKey = generateCacheKey(Array.isArray(keyFields) ? keyFields : [keyFields])
const rawValue = await client.get(cacheKey)
const value: JsonParsed<T> = rawValue ? JSON.parse(rawValue) : undefined
if (isDefined(value)) {
return parser ? parser(value as JsonParsed<NonNullable<T>>) : value
}
if (resolver) {
const newValue = await resolver()
if (isDefined(newValue)) {
if (ttl) {
await client.set(cacheKey, JSON.stringify(newValue), 'EX', ttl)
}
else {
await client.set(cacheKey, JSON.stringify(newValue))
}
return newValue
}
}
return defaultValue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment