lib/serverSWR.js (43 lines of code) (raw):
/*
* This file provides a fetch that uses node-cache under the covers to replicate SWR on the server.
* This enables caching to be handled in a specific way for API calls we're carrying
* out from the server.
*
*/
const crypto = require('crypto');
const NodeCache = require('node-cache');
const cache = new NodeCache();
// timeToStale is the amount of time that should pass before
// a cached results is considered stale.
// Default: 5 Minutes.
const TIME_TO_STALE_DEFAULT = 5 * 60 * 1000;
// staleMargin is added to the timstamp on stale requests
// to temporarily increase the time it's considered stale. This stops a
// lot of revalidation requests being made.
// Default: 10 Secs
const STALE_MARGIN_DEFAULT = 10 * 1000;
const serverSWR = async (
key,
fetcher,
{
timeToStale = TIME_TO_STALE_DEFAULT,
staleMargin = STALE_MARGIN_DEFAULT,
swrCache = cache,
hashKey = false,
} = {},
) => {
if (hashKey) {
key = crypto.createHash('sha256').update(key).digest('hex');
}
async function fetchAndCache() {
const result = await fetcher();
const cacheObject = {
timestamp: new Date().getTime(),
response: result,
};
swrCache.set(key, cacheObject);
return result;
}
if (swrCache.has(key)) {
const cachedData = swrCache.get(key);
if (typeof cachedData !== 'undefined') {
const currentTime = new Date().getTime();
if (currentTime > cachedData.timestamp + timeToStale) {
cachedData.timestamp = new Date().getTime() + staleMargin;
cachedData.response.stale = true;
// Re-insert the cache entry to update the timestamp.
// This prevents lots of revalidation requests.
swrCache.set(key, cachedData);
// Refetch async without waiting for the result.
fetchAndCache();
}
return cachedData.response;
}
}
return fetchAndCache();
};
module.exports = serverSWR;