Offer function to invalidate cached function
Describe the feature
I some cases I will know cache is invalid.
const { call: getAccessToken, invalidate: invalidateAccessToken } = defineCachedFunction(async () => {
const data = await fetch<any>('as/iam/authenticate', {
or
const getAccessToken = defineCachedFunction(async () => {
const data = await fetch<any>('as/iam/authenticate', {
…
}, {
maxAge: 595,
name: 'accessToken',
})
invalidateCachedFunction('accessToken')
Additional information
- [ ] Would you be willing to help implement this feature?
Is this what you're looking for ? https://github.com/unjs/nitro/blob/45f212bea448c69e5e9e8b069d0036611b80899f/examples/cached-handler/routes/index.ts#L5
but shouldInvalidateCache instead of shouldBypassCache ?
No, I need to clear cache when I get info about in different context.
5. 3. 2024 19:04:39, Adrien Zaganelli @.***> napsal:
I think this is what you're looking for :)
https://github.com/unjs/nitro/blob/45f212bea448c69e5e9e8b069d0036611b80899f/examples/cached-handler/routes/index.ts#L5
— Reply to this email directly, view it on GitHub https://github.com/unjs/nitro/issues/2218#issuecomment-1979343106, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEV6WD2YZNWPE2FTLQ427TYWYCLPAVCNFSM6AAAAABEF2HVD2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZZGM2DGMJQGY . You are receiving this because you authored the thread.Message ID: @.***>
When using defineCahedFunction, Nitro will generate a specific key (learn more):
`${options.group}:${options.name}:${options.getKey(...args)}.json`
- Default of
groupis'nitro:functions' - Default of
nameis'_'
So if you have the following:
const getAccessToken = defineCachedFunction(() => {
return String(Date.now())
}, {
maxAge: 10,
name: 'getAccessToken',
getKey: () => 'default'
})
It will save in the storage the following key:
nitro:functions:getAccessToken:default.json
You can access the cache storage using:
const cache = useStorage('cache')
Then if you want to invalidate the cached function:
const cache = useStorage('cache')
await cache.removeItem('nitro:functions:getAccessToken:default.json')
Hope that helps 😊
I think a nice option would be to expose a .invalidate() method (or we can find a better name) for it.
We could also expose some .meta() to know more about the cache options, key and next expiration.
const getAccessToken = defineCachedFunction(() => {
return String(Date.now())
}, {
maxAge: 10,
name: 'getAccessToken',
getKey: () => 'default'
})
// Get the meta
await getAccessToken.meta()
// Remove the entry in the cache storage
await getAccessToken.invalidate()
I think @pi0 may have some great ideas around it 💚
Another practical way would be:
const getAccessToken = defineCachedFunction((param: string) => {
return encode(param + String(Date.now()))
}, {
maxAge: 10,
})
await getAccessToken("foo") // cache miss
await getAccessToken("foo") // cache hit
await getAccessToken.withBypass("foo") // same as if shouldBypassCache() returned true
await getAccessToken.withInvalidate("foo") // same as if shouldInvalidateCache() returned true
I am using a wrapper for defineCachedFunction adding the above:
import type { CacheOptions } from "nitropack/types"
type CachedFunctionWithInvalidate<T, ArgsT extends unknown[] = any[]> = ((...args: ArgsT) => Promise<T>) & {
withInvalidate(...args: ArgsT): Promise<T>
}
export function defineCachedFunctionWithInvalidate<T, ArgsT extends unknown[] = any[]>(fn: (...args: ArgsT) => T | Promise<T>, opts?: CacheOptions<T, ArgsT>) {
let invalidated = false
const cachedFunction = defineCachedFunction(fn, {
...opts,
shouldInvalidateCache(...args) {
if (invalidated) {
invalidated = false
return true
}
return opts?.shouldInvalidateCache ? opts.shouldInvalidateCache(...args) : false
},
}) as CachedFunctionWithInvalidate<T, ArgsT>
cachedFunction.withInvalidate = (...args: ArgsT) => {
invalidated = true
return cachedFunction(...args)
}
return cachedFunction
}
then:
const getAccessToken = defineCachedFunctionWithInvalidate((param: string) => { ... })
await getAccessToken("foo") // normal use
await getAccessToken.withInvalidate("foo") // force invalidate