fix: unblock query cache mutations in demo mode and add cache buster (#6176)
This commit is contained in:
1 parent
529942e4da
commit
a382c75968
7 files changed
+52
-104
No files matched your search
@@ -6,12 +6,9 @@ interface Options<TData, TInput extends Record<string, unknown>> {
|
||||
type CacheEntry<TData> = { data: TData; timestamp: Date; expiresAt: number };
|
||||
|
||||
const MAX_CACHE_SIZE = 1000;
|
||||
const cache = new Map<string, CacheEntry<unknown>>();
|
||||
const inflight = new Map<string, Promise<CacheEntry<unknown>>>();
|
||||
|
||||
const DEFAULT_TTL_MS = 10_000;
|
||||
|
||||
const evictExpired = () => {
|
||||
const evictExpired = <TData>(cache: Map<string, CacheEntry<TData>>) => {
|
||||
const now = Date.now();
|
||||
for (const [key, entry] of cache) {
|
||||
if (now >= entry.expiresAt) cache.delete(key);
|
||||
@@ -20,41 +17,46 @@ const evictExpired = () => {
|
||||
|
||||
export const createRequestHandler = <TData, TInput extends Record<string, unknown>>(
|
||||
options: Options<TData, TInput>,
|
||||
) => ({
|
||||
handler: (input: TInput) => ({
|
||||
async getDataAsync(): Promise<{ data: TData; timestamp: Date }> {
|
||||
const ttl = options.cacheTtlMs ?? DEFAULT_TTL_MS;
|
||||
const key = JSON.stringify(input);
|
||||
) => {
|
||||
const cache = new Map<string, CacheEntry<TData>>();
|
||||
const inflight = new Map<string, Promise<CacheEntry<TData>>>();
|
||||
|
||||
const cached = cache.get(key) as CacheEntry<TData> | undefined;
|
||||
if (cached && Date.now() < cached.expiresAt) {
|
||||
return { data: cached.data, timestamp: cached.timestamp };
|
||||
}
|
||||
if (cached) cache.delete(key);
|
||||
return {
|
||||
handler: (input: TInput) => ({
|
||||
async getDataAsync(): Promise<{ data: TData; timestamp: Date }> {
|
||||
const ttl = options.cacheTtlMs ?? DEFAULT_TTL_MS;
|
||||
const key = JSON.stringify(input);
|
||||
|
||||
const existing = inflight.get(key);
|
||||
if (existing) return existing as Promise<CacheEntry<TData>>;
|
||||
const cached = cache.get(key);
|
||||
if (cached && Date.now() < cached.expiresAt) {
|
||||
return { data: cached.data, timestamp: cached.timestamp };
|
||||
}
|
||||
if (cached) cache.delete(key);
|
||||
|
||||
const promise = options
|
||||
.requestAsync(input)
|
||||
.then((data) => {
|
||||
if (cache.size >= MAX_CACHE_SIZE) evictExpired();
|
||||
if (cache.size >= MAX_CACHE_SIZE) {
|
||||
const oldest = cache.keys().next().value;
|
||||
if (oldest) cache.delete(oldest);
|
||||
}
|
||||
const entry: CacheEntry<TData> = { data, timestamp: new Date(), expiresAt: Date.now() + ttl };
|
||||
cache.set(key, entry as CacheEntry<unknown>);
|
||||
inflight.delete(key);
|
||||
return entry;
|
||||
})
|
||||
.catch((err) => {
|
||||
inflight.delete(key);
|
||||
throw err;
|
||||
});
|
||||
const existing = inflight.get(key);
|
||||
if (existing) return existing;
|
||||
|
||||
inflight.set(key, promise as Promise<CacheEntry<unknown>>);
|
||||
return promise;
|
||||
},
|
||||
}),
|
||||
});
|
||||
const promise = options
|
||||
.requestAsync(input)
|
||||
.then((data) => {
|
||||
if (cache.size >= MAX_CACHE_SIZE) evictExpired(cache);
|
||||
if (cache.size >= MAX_CACHE_SIZE) {
|
||||
const oldest = cache.keys().next().value;
|
||||
if (oldest) cache.delete(oldest);
|
||||
}
|
||||
const entry: CacheEntry<TData> = { data, timestamp: new Date(), expiresAt: Date.now() + ttl };
|
||||
cache.set(key, entry);
|
||||
inflight.delete(key);
|
||||
return entry;
|
||||
})
|
||||
.catch((err) => {
|
||||
inflight.delete(key);
|
||||
throw err;
|
||||
});
|
||||
|
||||
inflight.set(key, promise);
|
||||
return promise;
|
||||
},
|
||||
}),
|
||||
};
|
||||
};
|
||||
Reference in new issue
Block a user