@botonic/plugin-contentful
Version:
## What Does This Plugin Do?
108 lines • 3.38 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LimitedCacheDecorator = exports.InMemoryCache = exports.NOT_FOUND_IN_CACHE = void 0;
const objects_1 = require("./objects");
exports.NOT_FOUND_IN_CACHE = Symbol('NOT_FOUND');
class InMemoryCache {
constructor() {
this.cache = {};
this.sizeBytes = 0;
}
set(id, val) {
this.del(id);
this.sizeBytes += (0, objects_1.roughSizeOfObject)(id) + (0, objects_1.roughSizeOfObject)(val);
this.cache[id] = val;
}
del(id) {
const val = this.get(id);
if (val == exports.NOT_FOUND_IN_CACHE) {
return;
}
delete this.cache[id];
this.sizeBytes -= (0, objects_1.roughSizeOfObject)(id) + (0, objects_1.roughSizeOfObject)(val);
}
get(id) {
// Cache.has is only checked when undefined to avoid always searching twice in the object
const val = this.cache[id];
if (val === undefined && !this.has(id)) {
return exports.NOT_FOUND_IN_CACHE;
}
return val;
}
has(id) {
return id in this.cache;
}
size() {
return this.sizeBytes / 1024;
}
len() {
return Object.keys(this.cache).length;
}
*keys() {
for (const k of Object.keys(this.cache)) {
yield k;
}
}
}
exports.InMemoryCache = InMemoryCache;
/**
* Decorates a cache by limiting its size.
*
* TODO Use an external library to have a LRU cache. However, it's not critical
* because typically data in CMS is small (we're not caching media, only their
* URLs)
*/
class LimitedCacheDecorator {
constructor(cache, limitKB, logger = console.error, sizeWarningsRatio = [0.5, 0.75, 0.9]) {
this.cache = cache;
this.limitKB = limitKB;
this.logger = logger;
this.sizeWarningsRatio = sizeWarningsRatio;
}
set(id, val) {
const incBytes = (0, objects_1.roughSizeOfObject)(id) + (0, objects_1.roughSizeOfObject)(val);
const checkFit = () => this.cache.size() * 1024 + incBytes <= this.limitKB * 1024;
let itFits = checkFit();
if (!itFits) {
for (const k of this.cache.keys()) {
if (itFits) {
break;
}
this.cache.del(k);
itFits = checkFit();
}
if (!itFits) {
this.logger(`Cannot add entry in cache because IT ALONE is larger than max capacity(${this.limitKB})`);
return;
}
}
this.cache.set(id, val);
this.warnSizeRatio(incBytes / 1024);
}
warnSizeRatio(incKB) {
const sizeKB = this.size();
for (const warnRatio of this.sizeWarningsRatio.sort((a, b) => b - a)) {
if (sizeKB / this.limitKB >= warnRatio && sizeKB - incKB < warnRatio) {
this.logger(`Cache is now more than ${warnRatio * 100}% full`);
return;
}
}
}
get(id) {
return this.cache.get(id);
}
has(id) {
return this.cache.has(id);
}
del(id) {
return this.cache.del(id);
}
keys() {
return this.cache.keys();
}
size() {
return this.cache.size();
}
}
exports.LimitedCacheDecorator = LimitedCacheDecorator;
//# sourceMappingURL=cache.js.map