@blocklet/payment-react
Version:
Reusable react components for payment kit v2
78 lines (77 loc) • 2.07 kB
JavaScript
import { globalCache } from "./cache.js";
export class CachedRequest {
cacheKey;
fetchData;
options;
constructor(cacheKey, fetchData, options = {}) {
this.cacheKey = cacheKey;
this.fetchData = fetchData;
this.options = {
strategy: "session",
ttl: 0,
...options
};
}
getCache() {
const { strategy } = this.options;
switch (strategy) {
case "local":
return localStorage;
case "memory":
return globalCache;
case "session":
default:
return sessionStorage;
}
}
getCachedData() {
const cache = this.getCache();
const data = this.options.strategy === "memory" ? cache.get(this.cacheKey) : cache.getItem(this.cacheKey);
if (!data) return null;
const parsed = JSON.parse(data);
if (this.options.ttl && parsed.timestamp) {
const isExpired = Date.now() - parsed.timestamp > this.options.ttl;
if (isExpired) {
this.clearCache();
return null;
}
}
return parsed.data;
}
setCachedData(data) {
const cache = this.getCache();
const value = JSON.stringify({
data,
timestamp: Date.now()
});
if (this.options.strategy === "memory") {
cache.set(this.cacheKey, value);
} else {
cache.setItem(this.cacheKey, value);
}
}
clearCache() {
const cache = this.getCache();
if (this.options.strategy === "memory") {
cache.delete(this.cacheKey);
} else {
cache.removeItem(this.cacheKey);
}
}
fetch(forceRefresh = false) {
const cachedData = !forceRefresh && this.getCachedData();
if (cachedData) return Promise.resolve(cachedData);
const globalItem = globalCache.get(this.cacheKey);
if (globalItem?.promise) {
return globalItem.promise;
}
const newPromise = this.fetchData().then(({ data }) => {
this.setCachedData(data);
return data;
}).finally(() => {
globalCache.delete(this.cacheKey);
});
globalCache.set(this.cacheKey, { promise: newPromise });
return newPromise;
}
}