@splitsoftware/splitio-commons
Version:
Split JavaScript SDK common components
192 lines (191 loc) • 8.19 kB
JavaScript
import { __extends } from "tslib";
import { AbstractDefinitionsCacheSync, usesSegments } from '../AbstractDefinitionsCacheSync';
import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
import { LOG_PREFIX } from './constants';
import { setToArray } from '../../utils/lang/sets';
var DefinitionsCacheInLocal = /** @class */ (function (_super) {
__extends(DefinitionsCacheInLocal, _super);
function DefinitionsCacheInLocal(settings, keys, storage) {
var _this = _super.call(this) || this;
_this.keys = keys;
_this.log = settings.log;
_this.setsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
_this.storage = storage;
return _this;
}
DefinitionsCacheInLocal.prototype._decrementCount = function (key) {
var count = toNumber(this.storage.getItem(key)) - 1;
if (count > 0)
this.storage.setItem(key, count + '');
else
this.storage.removeItem(key);
};
DefinitionsCacheInLocal.prototype._decrementCounts = function (definition) {
try {
var ttKey = this.keys.buildTrafficTypeKey(definition.trafficTypeName);
this._decrementCount(ttKey);
if (usesSegments(definition)) {
var segmentsCountKey = this.keys.buildDefinitionsWithSegmentCountKey();
this._decrementCount(segmentsCountKey);
}
}
catch (e) {
this.log.error(LOG_PREFIX + e);
}
};
DefinitionsCacheInLocal.prototype._incrementCounts = function (definition) {
try {
var ttKey = this.keys.buildTrafficTypeKey(definition.trafficTypeName);
this.storage.setItem(ttKey, (toNumber(this.storage.getItem(ttKey)) + 1) + '');
if (usesSegments(definition)) {
var segmentsCountKey = this.keys.buildDefinitionsWithSegmentCountKey();
this.storage.setItem(segmentsCountKey, (toNumber(this.storage.getItem(segmentsCountKey)) + 1) + '');
}
}
catch (e) {
this.log.error(LOG_PREFIX + e);
}
};
/**
* Removes all definitions related data from localStorage (splits, counters, changeNumber and lastUpdated).
* We cannot simply call `localStorage.clear()` since that implies removing user items from the storage.
*/
DefinitionsCacheInLocal.prototype.clear = function () {
var _this = this;
// collect item keys
var len = this.storage.length;
var accum = [];
for (var cur = 0; cur < len; cur++) {
var key = this.storage.key(cur);
if (key != null && this.keys.isDefinitionsCacheKey(key))
accum.push(key);
}
// remove items
accum.forEach(function (key) {
_this.storage.removeItem(key);
});
this.hasSync = false;
};
DefinitionsCacheInLocal.prototype.add = function (definition) {
var name = definition.name;
var definitionKey = this.keys.buildDefinitionKey(name);
var definitionFromStorage = this.storage.getItem(definitionKey);
var previousDefinition = definitionFromStorage ? JSON.parse(definitionFromStorage) : null;
if (previousDefinition) {
this._decrementCounts(previousDefinition);
this.removeFromSets(previousDefinition.name, previousDefinition.sets);
}
this.storage.setItem(definitionKey, JSON.stringify(definition));
this._incrementCounts(definition);
this.addToSets(definition);
return true;
};
DefinitionsCacheInLocal.prototype.remove = function (name) {
var definition = this.get(name);
if (!definition)
return false;
this.storage.removeItem(this.keys.buildDefinitionKey(name));
this._decrementCounts(definition);
this.removeFromSets(definition.name, definition.sets);
return true;
};
DefinitionsCacheInLocal.prototype.get = function (name) {
var item = this.storage.getItem(this.keys.buildDefinitionKey(name));
return item && JSON.parse(item);
};
DefinitionsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
try {
this.storage.setItem(this.keys.buildDefinitionsTillKey(), changeNumber + '');
// update "last updated" timestamp with current time
this.storage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
this.hasSync = true;
return true;
}
catch (e) {
this.log.error(LOG_PREFIX + e);
return false;
}
};
DefinitionsCacheInLocal.prototype.getChangeNumber = function () {
var n = -1;
var value = this.storage.getItem(this.keys.buildDefinitionsTillKey());
if (value !== null) {
value = parseInt(value, 10);
return isNaNNumber(value) ? n : value;
}
return n;
};
DefinitionsCacheInLocal.prototype.getNames = function () {
var len = this.storage.length;
var accum = [];
var cur = 0;
while (cur < len) {
var key = this.storage.key(cur);
if (key != null && this.keys.isDefinitionKey(key))
accum.push(this.keys.extractKey(key));
cur++;
}
return accum;
};
DefinitionsCacheInLocal.prototype.trafficTypeExists = function (trafficType) {
var ttCount = toNumber(this.storage.getItem(this.keys.buildTrafficTypeKey(trafficType)));
return isFiniteNumber(ttCount) && ttCount > 0;
};
DefinitionsCacheInLocal.prototype.usesSegments = function () {
// If cache hasn't been synchronized with the cloud, assume we need them.
if (!this.hasSync)
return true;
var storedCount = this.storage.getItem(this.keys.buildDefinitionsWithSegmentCountKey());
var definitionsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
return isFiniteNumber(definitionsWithSegmentsCount) ?
definitionsWithSegmentsCount > 0 :
true;
};
DefinitionsCacheInLocal.prototype.getNamesBySets = function (sets) {
var _this = this;
return sets.map(function (set) {
var setKey = _this.keys.buildSetKey(set);
var setFromStorage = _this.storage.getItem(setKey);
return new Set(setFromStorage ? JSON.parse(setFromStorage) : []);
});
};
DefinitionsCacheInLocal.prototype.addToSets = function (definition) {
var _this = this;
if (!definition.sets)
return;
definition.sets.forEach(function (set) {
if (_this.setsFilter.length > 0 && !_this.setsFilter.some(function (filterSet) { return filterSet === set; }))
return;
var setKey = _this.keys.buildSetKey(set);
var setFromStorage = _this.storage.getItem(setKey);
var setCache = new Set(setFromStorage ? JSON.parse(setFromStorage) : []);
if (setCache.has(definition.name))
return;
setCache.add(definition.name);
_this.storage.setItem(setKey, JSON.stringify(setToArray(setCache)));
});
};
DefinitionsCacheInLocal.prototype.removeFromSets = function (definitionName, sets) {
var _this = this;
if (!sets)
return;
sets.forEach(function (set) {
_this.removeNames(set, definitionName);
});
};
DefinitionsCacheInLocal.prototype.removeNames = function (setName, definitionName) {
var setKey = this.keys.buildSetKey(setName);
var setFromStorage = this.storage.getItem(setKey);
if (!setFromStorage)
return;
var setCache = new Set(JSON.parse(setFromStorage));
setCache.delete(definitionName);
if (setCache.size === 0) {
this.storage.removeItem(setKey);
return;
}
this.storage.setItem(setKey, JSON.stringify(setToArray(setCache)));
};
return DefinitionsCacheInLocal;
}(AbstractDefinitionsCacheSync));
export { DefinitionsCacheInLocal };