@ima/core
Version:
IMA.js framework for isomorphic javascript application
172 lines (171 loc) • 5.55 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "CacheImpl", {
enumerable: true,
get: function() {
return CacheImpl;
}
});
const _Cache = require("./Cache");
const _CacheEntry = require("./CacheEntry");
class CacheImpl extends _Cache.Cache {
_cache;
_factory;
_Helper;
_ttl;
_enabled;
/**
* Initializes the cache.
*
* @param cacheStorage The cache entry storage to use.
* @param factory Which create new instance of cache entry.
* @param Helper The IMA.js helper methods.
* @param config The cache configuration.
*/ constructor(cacheStorage, factory, Helper, { ttl = 30000, enabled = false }){
super();
this._cache = cacheStorage;
this._factory = factory;
/**
* Tha IMA.js helper methods.
*/ this._Helper = Helper;
/**
* Default cache entry time to live in milliseconds.
*/ this._ttl = ttl;
/**
* Flag signalling whether the cache is currently enabled.
*/ this._enabled = enabled;
}
/**
* @inheritDoc
*/ clear() {
this._cache.clear();
}
/**
* @inheritDoc
*/ has(key) {
if (!this._enabled || !this._cache.has(key)) {
return false;
}
const cacheEntry = this._cache.get(key);
if (cacheEntry && !cacheEntry.isExpired()) {
return true;
}
this.delete(key);
return false;
}
/**
* @inheritDoc
*/ get(key) {
if (this.has(key)) {
const cacheEntryItem = this._cache.get(key);
const value = cacheEntryItem.getValue();
return this._clone(value);
}
return null;
}
/**
* @inheritDoc
*/ set(key, value, ttl = 0) {
if (!this._enabled) {
return;
}
const cacheEntry = this._factory.createCacheEntry(this._clone(value), ttl || this._ttl);
this._cache.set(key, cacheEntry);
}
/**
* @inheritDoc
*/ delete(key) {
this._cache.delete(key);
}
/**
* @inheritDoc
*/ disable() {
this._enabled = false;
this.clear();
}
/**
* @inheritDoc
*/ enable() {
this._enabled = true;
}
/**
* @inheritDoc
*/ serialize() {
const dataToSerialize = {};
for (const key of this._cache.keys()){
const currentValue = this._cache.get(key);
if (currentValue instanceof _CacheEntry.CacheEntry) {
const serializeEntry = currentValue.serialize();
if (serializeEntry.ttl === Infinity) {
serializeEntry.ttl = 'Infinity';
}
if ($Debug) {
if (!this._canSerializeValue(serializeEntry.value)) {
throw new Error(`ima.core.cache.CacheImpl:serialize An ` + `attempt to serialize ` + `${serializeEntry.toString()}, stored ` + `using the key ${key}, was made, but the value ` + `cannot be serialized. Remove this entry from ` + `the cache or change its type so that can be ` + `serialized using JSON.stringify().`);
}
}
dataToSerialize[key] = serializeEntry;
}
}
return JSON.stringify(dataToSerialize).replace(/<\/script/gi, '<\\/script');
}
/**
* @inheritDoc
*/ deserialize(serializedData) {
for (const key of Object.keys(serializedData)){
const cacheEntryItem = serializedData[key];
if (cacheEntryItem.ttl === 'Infinity') {
cacheEntryItem.ttl = Infinity;
}
this.set(key, cacheEntryItem.value, cacheEntryItem.ttl);
}
}
/**
* Tests whether the provided value can be serialized into JSON.
*
* @param value The value to test whether or not it can be serialized.
* @return `true` if the provided value can be serialized into JSON,
* `false` otherwise.
*/ _canSerializeValue(value) {
if (value instanceof Date || value instanceof RegExp || value instanceof Promise || typeof value === 'function') {
console.warn('The provided value is not serializable: ', value);
return false;
}
if (!value) {
return true;
}
if (value.constructor === Array) {
for (const element of value){
if (!this._canSerializeValue(element)) {
console.warn('The provided array is not serializable: ', value);
return false;
}
}
}
if (typeof value === 'object') {
for (const propertyName of Object.keys(value)){
if (!this._canSerializeValue(value[propertyName])) {
console.warn('The provided object is not serializable due to the ' + 'following property: ', propertyName, value);
return false;
}
}
}
return true;
}
/**
* Attempts to clone the provided value, if possible. Values that cannot be
* cloned (e.g. promises) will be simply returned.
*
* @param value The value to clone.
* @return The created clone, or the provided value if the value cannot be
* cloned.
*/ _clone(value) {
if (value !== null && typeof value === 'object' && !(value instanceof Promise)) {
return this._Helper.clone(value);
}
return value;
}
}
//# sourceMappingURL=CacheImpl.js.map