mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-28 06:09:06 +01:00
73 lines
2.5 KiB
JavaScript
73 lines
2.5 KiB
JavaScript
import { filter, map, merge, pipe, share, tap } from 'wonka';
|
|
|
|
/*
|
|
* Alternative to the default cacheExchange from urql (A GraphQL client).
|
|
* Mutations do not invalidate cached results, so in that regard, this
|
|
* implementation is inferior to the default one. Most people should probably
|
|
* use the standard cacheExchange and @urql/exchange-request-policy. This cache
|
|
* also ignores the 'network-and-cache' request policy.
|
|
*
|
|
* Options:
|
|
* ttl: How long queries are allowed to be cached (in milliseconds)
|
|
* maxSize: Max number of results cached. The oldest queries are removed first.
|
|
*/
|
|
export const expiringCacheExchange = ({ ttl, maxSize }) => ({ forward }) => {
|
|
const cache = new Map();
|
|
const isCached = (operation) => {
|
|
if (operation.kind !== 'query' || operation.context.requestPolicy === 'network-only')
|
|
return false;
|
|
|
|
if (!cache.has(operation.key))
|
|
return false;
|
|
|
|
let cacheEntry = cache.get(operation.key);
|
|
return Date.now() < cacheEntry.expiresAt;
|
|
};
|
|
|
|
return operations => {
|
|
let shared = share(operations);
|
|
return merge([
|
|
pipe(
|
|
shared,
|
|
filter(operation => isCached(operation)),
|
|
map(operation => cache.get(operation.key).response)
|
|
),
|
|
pipe(
|
|
shared,
|
|
filter(operation => !isCached(operation)),
|
|
forward,
|
|
tap(response => {
|
|
if (!response.operation || response.operation.kind !== 'query')
|
|
return;
|
|
|
|
if (!response.data)
|
|
return;
|
|
|
|
let now = Date.now();
|
|
for (let cacheEntry of cache.values()) {
|
|
if (cacheEntry.expiresAt < now) {
|
|
cache.delete(cacheEntry.response.operation.key);
|
|
}
|
|
}
|
|
|
|
if (cache.size > maxSize) {
|
|
let n = cache.size - maxSize + 1;
|
|
for (let key of cache.keys()) {
|
|
if (n-- == 0)
|
|
break;
|
|
|
|
cache.delete(key);
|
|
}
|
|
}
|
|
|
|
cache.set(response.operation.key, {
|
|
expiresAt: now + ttl,
|
|
response: response
|
|
});
|
|
})
|
|
)
|
|
]);
|
|
};
|
|
};
|
|
|