ng2-cache
Version:
Client side caching for Angular5
544 lines (531 loc) • 12.6 kB
JavaScript
/**
* @license ng2-cache
* MIT license
*/
import { Injectable, NgModule, Optional } from '@angular/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Abstract cache storage
* @abstract
*/
class CacheStorageAbstract {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Service for storing data in session storage
*/
class CacheSessionStorage extends CacheStorageAbstract {
/**
* @param {?} key
* @return {?}
*/
getItem(key) {
let /** @type {?} */ value = sessionStorage.getItem(key);
return value ? JSON.parse(value) : null;
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setItem(key, value) {
try {
sessionStorage.setItem(key, JSON.stringify(value));
return true;
}
catch (/** @type {?} */ e) {
return false;
}
}
/**
* @param {?} key
* @return {?}
*/
removeItem(key) {
sessionStorage.removeItem(key);
}
/**
* @return {?}
*/
clear() {
sessionStorage.clear();
}
/**
* @return {?}
*/
type() {
return 1 /* SESSION_STORAGE */;
}
/**
* @return {?}
*/
isEnabled() {
try {
sessionStorage.setItem('test', 'test');
sessionStorage.removeItem('test');
return true;
}
catch (/** @type {?} */ e) {
return false;
}
}
}
CacheSessionStorage.decorators = [
{ type: Injectable },
];
/** @nocollapse */
CacheSessionStorage.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Service for storing data in local storage
*/
class CacheLocalStorage extends CacheStorageAbstract {
/**
* @param {?} key
* @return {?}
*/
getItem(key) {
const /** @type {?} */ value = localStorage.getItem(key);
return value ? JSON.parse(value) : null;
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setItem(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
}
catch (/** @type {?} */ e) {
return false;
}
}
/**
* @param {?} key
* @return {?}
*/
removeItem(key) {
localStorage.removeItem(key);
}
/**
* @return {?}
*/
clear() {
localStorage.clear();
}
/**
* @return {?}
*/
type() {
return 0 /* LOCAL_STORAGE */;
}
/**
* @return {?}
*/
isEnabled() {
try {
localStorage.setItem('test', 'test');
localStorage.removeItem('test');
return true;
}
catch (/** @type {?} */ e) {
return false;
}
}
}
CacheLocalStorage.decorators = [
{ type: Injectable },
];
/** @nocollapse */
CacheLocalStorage.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Service for storing data in local storage
*/
class CacheMemoryStorage extends CacheStorageAbstract {
constructor() {
super(...arguments);
this._data = {};
}
/**
* @param {?} key
* @return {?}
*/
getItem(key) {
return this._data[key] ? this._data[key] : null;
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setItem(key, value) {
this._data[key] = value;
return true;
}
/**
* @param {?} key
* @return {?}
*/
removeItem(key) {
delete this._data[key];
}
/**
* @return {?}
*/
clear() {
this._data = [];
}
/**
* @return {?}
*/
type() {
return 2 /* MEMORY */;
}
/**
* @return {?}
*/
isEnabled() {
return true;
}
}
CacheMemoryStorage.decorators = [
{ type: Injectable },
];
/** @nocollapse */
CacheMemoryStorage.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const CACHE_PREFIX = 'CacheService';
const DEFAULT_STORAGE = 1;
const DEFAULT_ENABLED_STORAGE = 2;
class CacheService {
/**
* @param {?} _storage
*/
constructor(_storage) {
this._storage = _storage;
/**
* Default cache options
*/
this._defaultOptions = {
expires: Number.MAX_VALUE,
maxAge: Number.MAX_VALUE
};
/**
* Cache prefix
*/
this._prefix = CACHE_PREFIX;
this._validateStorage();
}
/**
* Set data to cache
* @param {?} key
* @param {?} value
* @param {?=} options
* @return {?}
*/
set(key, value, options) {
let /** @type {?} */ storageKey = this._toStorageKey(key);
options = options ? options : this._defaultOptions;
if (this._storage.setItem(storageKey, this._toStorageValue(value, options))) {
if (!this._isSystemKey(key) && options.tag) {
this._saveTag(options.tag, storageKey);
}
return true;
}
return false;
}
/**
* Get data from cache
* @param {?} key
* @return {?} any
*/
get(key) {
let /** @type {?} */ storageValue = this._storage.getItem(this._toStorageKey(key)), /** @type {?} */
value = null;
if (storageValue) {
if (this._validateStorageValue(storageValue)) {
value = storageValue.value;
}
else {
this.remove(key);
}
}
return value;
}
/**
* Check if value exists
* @param {?} key
* @return {?} boolean
*/
exists(key) {
return !!this.get(key);
}
/**
* Remove item from cache
* @param {?} key
* @return {?}
*/
remove(key) {
this._storage.removeItem(this._toStorageKey(key));
this._removeFromTag(this._toStorageKey(key));
}
/**
* Remove all from cache
* @return {?}
*/
removeAll() {
this._storage.clear();
}
/**
* Get all tag data
* @param {?} tag
* @return {?} Array
*/
getTagData(tag) {
let /** @type {?} */ tags = this.get(this._tagsStorageKey()) || {}, /** @type {?} */
result = {};
if (tags[tag]) {
tags[tag].forEach((key) => {
let /** @type {?} */ data = this.get(this._fromStorageKey(key));
if (data) {
result[this._fromStorageKey(key)] = data;
}
});
}
return result;
}
/**
* Create a new instance of cache with needed storage
* @param {?} type
* returns CacheService
* @return {?}
*/
useStorage(type) {
let /** @type {?} */ service = new CacheService(this._initStorage(type));
service.setGlobalPrefix(this._getCachePrefix());
return service;
}
/**
* Remove all by tag
* @param {?} tag
* @return {?}
*/
removeTag(tag) {
let /** @type {?} */ tags = this.get(this._tagsStorageKey()) || {};
if (tags[tag]) {
tags[tag].forEach((key) => {
this._storage.removeItem(key);
});
delete tags[tag];
this.set(this._tagsStorageKey(), tags);
}
}
/**
* Set global cache key prefix
* @param {?} prefix
* @return {?}
*/
setGlobalPrefix(prefix) {
this._prefix = prefix;
}
/**
* Validate cache storage
* @return {?}
*/
_validateStorage() {
if (!this._storage) {
this._storage = this._initStorage(DEFAULT_STORAGE);
}
if (!this._storage.isEnabled()) {
this._storage = this._initStorage(DEFAULT_ENABLED_STORAGE);
}
}
/**
* Remove key from tags keys list
* @param {?} key
* @return {?}
*/
_removeFromTag(key) {
let /** @type {?} */ tags = this.get(this._tagsStorageKey()) || {}, /** @type {?} */
index;
for (let /** @type {?} */ tag in tags) {
index = tags[tag].indexOf(key);
if (index !== -1) {
tags[tag].splice(index, 1);
this.set(this._tagsStorageKey(), tags);
break;
}
}
}
/**
* Init storage by type
* @param {?} type
* @return {?} CacheStorageAbstract
*/
_initStorage(type) {
let /** @type {?} */ storage;
switch (type) {
case 1 /* SESSION_STORAGE */:
storage = new CacheSessionStorage();
break;
case 0 /* LOCAL_STORAGE */:
storage = new CacheLocalStorage();
break;
default: storage = new CacheMemoryStorage();
}
return storage;
}
/**
* @param {?} key
* @return {?}
*/
_toStorageKey(key) {
return this._getCachePrefix() + key;
}
/**
* @param {?} key
* @return {?}
*/
_fromStorageKey(key) {
return key.replace(this._getCachePrefix(), '');
}
/**
* Prepare value to set to storage
* @param {?} value
* @param {?} options
* returns {value: any, options: CacheOptionsInterface}
* @return {?}
*/
_toStorageValue(value, options) {
return {
value: value,
options: this._toStorageOptions(options)
};
}
/**
* Prepare options to set to storage
* @param {?} options
* @return {?} CacheOptionsInterface
*/
_toStorageOptions(options) {
var /** @type {?} */ storageOptions = {};
storageOptions.expires = options.expires ? options.expires :
(options.maxAge ? Date.now() + (options.maxAge * 1000) : this._defaultOptions.expires);
storageOptions.maxAge = options.maxAge ? options.maxAge : this._defaultOptions.maxAge;
return storageOptions;
}
/**
* Validate storage value
* @param {?} value
* @return {?} boolean
*/
_validateStorageValue(value) {
return !!value.options.expires && value.options.expires > Date.now();
}
/**
* check if its system cache key
* @param {?} key
* returns boolean
* @return {?}
*/
_isSystemKey(key) {
return [this._tagsStorageKey()].indexOf(key) !== -1;
}
/**
* Save tag to list of tags
* @param {?} tag
* @param {?} key
* @return {?}
*/
_saveTag(tag, key) {
let /** @type {?} */ tags = this.get(this._tagsStorageKey()) || {};
if (!tags[tag]) {
tags[tag] = [key];
}
else {
tags[tag].push(key);
}
this.set(this._tagsStorageKey(), tags);
}
/**
* Get global cache prefix
* returns {string}
* private
* @return {?}
*/
_getCachePrefix() {
return this._prefix;
}
/**
* @return {?}
*/
_tagsStorageKey() {
return 'CacheService_tags';
}
}
CacheService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
CacheService.ctorParameters = () => [
{ type: CacheStorageAbstract, decorators: [{ type: Optional },] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class Ng2CacheModule {
}
Ng2CacheModule.decorators = [
{ type: NgModule, args: [{
providers: [CacheService]
},] },
];
/** @nocollapse */
Ng2CacheModule.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Angular library starter
* Build an Angular library compatible with AoT compilation & Tree shaking like an official package
* Copyright Roberto Simonetti
* MIT license
* https://github.com/robisim74/angular-library-starter
*/
/**
* Entry point for all public APIs of the package.
*/
// This file only reexports content of the `src` folder. Keep it that way.
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Generated bundle index. Do not edit.
*/
export { CacheService, CacheStorageAbstract, CacheLocalStorage, CacheMemoryStorage, CacheSessionStorage, Ng2CacheModule };
//# sourceMappingURL=ng2-cache.js.map