angular-web-store
Version:
## Installation
563 lines (552 loc) • 15.2 kB
JavaScript
import { Inject, Injectable, InjectionToken, NgModule } from '@angular/core';
import { Subject } from 'rxjs';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;
/**
* @param {?} val
* @param {?=} options
* @return {?}
*/
function ms(val, options) {
options = options || {};
if (typeof val === 'string' && val.length > 0) {
return parse(val);
}
else if (typeof val === 'number' && isNaN(val) === false) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error('val is not a non-empty string or a valid number. val=' +
JSON.stringify(val));
}
/**
* Parse the given `str` and return milliseconds.
*
* \@api private
* @param {?} str
* @return {?}
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var /** @type {?} */ match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
if (!match) {
return;
}
var /** @type {?} */ n = parseFloat(match[1]);
var /** @type {?} */ type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* \@api private
* @param {?} mills
* @return {?}
*/
function fmtShort(mills) {
if (mills >= d) {
return Math.round(mills / d) + 'd';
}
if (mills >= h) {
return Math.round(mills / h) + 'h';
}
if (mills >= m) {
return Math.round(mills / m) + 'm';
}
if (mills >= s) {
return Math.round(mills / s) + 's';
}
return mills + 'ms';
}
/**
* Long format for `ms`.
*
* \@api private
* @param {?} mills
* @return {?}
*/
function fmtLong(mills) {
return (plural(mills, d, 'day') ||
plural(mills, h, 'hour') ||
plural(mills, m, 'minute') ||
plural(mills, s, 'second') ||
mills + ' ms');
}
/**
* Pluralization helper.
* @param {?} mills
* @param {?} n
* @param {?} name
* @return {?}
*/
function plural(mills, n, name) {
if (mills < n) {
return;
}
if (mills < n * 1.5) {
return Math.floor(mills / n) + ' ' + name;
}
return Math.ceil(mills / n) + ' ' + name + 's';
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @record
*/
var SetAction = /** @class */ (function () {
function SetAction(key, value, expiredIn) {
this.key = key;
this.value = value;
this.expiredIn = expiredIn;
}
SetAction.TYPE = 'set';
return SetAction;
}());
var GetAction = /** @class */ (function () {
function GetAction(key) {
this.key = key;
}
GetAction.TYPE = 'get';
return GetAction;
}());
var RemoveAction = /** @class */ (function () {
function RemoveAction(key) {
this.key = key;
}
RemoveAction.TYPE = 'remove';
return RemoveAction;
}());
var ClearAction = /** @class */ (function () {
function ClearAction() {
}
ClearAction.TYPE = 'clear';
return ClearAction;
}());
/**
* @record
*/
var ANGULAR_WEB_STORE_CONFIG = new InjectionToken('ANGULAR_WEB_STORE_CONFIG');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @record
*/
var SESSION_STORAGE_NOT_SUPPORTED = {
code: 100,
message: 'Session storage not supported!'
};
var LOCAL_STORAGE_NOT_SUPPORTED = {
code: 200,
message: 'Local storage not supported!'
};
var UNKNOWN_STORAGE_TYPE = {
code: 300,
message: 'Unknown storage type!'
};
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/** @enum {string} */
var StorageType = {
LOCAL: 'localStorage',
SESSION: 'sessionStorage',
};
var EXPIRED_AT = '@@EXPIRED_AT';
var STOREAGE_VALUE = '@@STORAGE_VALUE';
var EXPIRED_MS = '@@EXPIRED_MS';
var StorageService = /** @class */ (function () {
function StorageService(storageType, config) {
this.storageType = storageType;
this.config = config;
this.errors = new Subject();
this.actions = new Subject();
this.initConfig(config);
this.initStorage(storageType);
}
/**
* set key,value to storage
*
* @param {string} key
* @param {*} value
* @param {string} [expiredIn] ex: '3ms' '4s' '5m' '6h' '7d' '8y'
* @memberof StorageService
*/
/**
* set key,value to storage
*
* \@memberof StorageService
* @param {?} key
* @param {?} value
* @param {?=} expiredIn
* @return {?}
*/
StorageService.prototype.set = /**
* set key,value to storage
*
* \@memberof StorageService
* @param {?} key
* @param {?} value
* @param {?=} expiredIn
* @return {?}
*/
function (key, value, expiredIn) {
this.notifyAction(SetAction.TYPE, new SetAction(key, value, expiredIn));
var /** @type {?} */ expiredMs = this.computeExpiredMs(expiredIn);
this.storage.setItem(this.computeKey(key), JSON.stringify((_a = {},
_a[EXPIRED_MS] = expiredMs,
_a[EXPIRED_AT] = expiredMs === -1 ? -1 : +new Date() + expiredMs,
_a[STOREAGE_VALUE] = value,
_a)));
var _a;
};
/**
* get value from storage of key
*
* @param {string} key
* @returns {*}
* @memberof StorageService
*/
/**
* get value from storage of key
*
* \@memberof StorageService
* @param {?} key
* @return {?}
*/
StorageService.prototype.get = /**
* get value from storage of key
*
* \@memberof StorageService
* @param {?} key
* @return {?}
*/
function (key) {
this.notifyAction(GetAction.TYPE, new GetAction(key));
try {
var /** @type {?} */ obj = JSON.parse(this.storage.getItem(this.computeKey(key)) || 'null');
if (this.isValidValue(obj)) {
if (this.unExpired(obj[EXPIRED_AT])) {
var /** @type {?} */ value = obj[STOREAGE_VALUE];
if (obj[EXPIRED_AT] !== -1 && this.keepAlive) {
this.set(key, value, String(obj[EXPIRED_MS]) + 'ms');
}
return value;
}
else {
this.storage.removeItem(this.computeKey(key));
return null;
}
}
return null;
}
catch (/** @type {?} */ e) {
return null;
}
};
/**
* remove value from storage of key
*
* @param {string} key
* @memberof StorageService
*/
/**
* remove value from storage of key
*
* \@memberof StorageService
* @param {?} key
* @return {?}
*/
StorageService.prototype.remove = /**
* remove value from storage of key
*
* \@memberof StorageService
* @param {?} key
* @return {?}
*/
function (key) {
this.notifyAction(RemoveAction.TYPE, new RemoveAction(key));
this.storage.removeItem(this.computeKey(key));
};
/**
* clear all storage
*
* @memberof StorageService
*/
/**
* clear all storage
*
* \@memberof StorageService
* @return {?}
*/
StorageService.prototype.clear = /**
* clear all storage
*
* \@memberof StorageService
* @return {?}
*/
function () {
this.notifyAction(ClearAction.TYPE, new ClearAction());
this.storage.clear();
};
/**
* @param {?} config
* @return {?}
*/
StorageService.prototype.initConfig = /**
* @param {?} config
* @return {?}
*/
function (config) {
this.prefix = config.prefix || 'MIZNE';
this.expiredMs = config.expiredIn ? ms(config.expiredIn) : -1;
this.actionNotify = config.actionNotify || {};
this.keepAlive = config.keepAlive || false;
};
/**
* @param {?} storageType
* @return {?}
*/
StorageService.prototype.initStorage = /**
* @param {?} storageType
* @return {?}
*/
function (storageType) {
switch (storageType) {
case StorageType.LOCAL:
if (this.checkSupport(storageType)) {
this.storage = window[storageType];
}
else {
this.errors.next(LOCAL_STORAGE_NOT_SUPPORTED);
}
break;
case StorageType.SESSION:
if (this.checkSupport(storageType)) {
this.storage = window[storageType];
}
else {
this.errors.next(SESSION_STORAGE_NOT_SUPPORTED);
}
break;
default:
this.errors.next(UNKNOWN_STORAGE_TYPE);
break;
}
};
/**
* @param {?} storageType
* @return {?}
*/
StorageService.prototype.checkSupport = /**
* @param {?} storageType
* @return {?}
*/
function (storageType) {
try {
if (storageType in window && window[storageType] !== null) {
var /** @type {?} */ webStorage = window[storageType];
var /** @type {?} */ key = this.prefix + "_CHECK_SUPPORT";
webStorage.setItem(key, '');
webStorage.removeItem(key);
return true;
}
}
catch (/** @type {?} */ e) {
this.errors.next({ code: 500, message: e.message });
}
return false;
};
/**
* @param {?} expiredIn
* @return {?}
*/
StorageService.prototype.computeExpiredMs = /**
* @param {?} expiredIn
* @return {?}
*/
function (expiredIn) {
return expiredIn ? ms(expiredIn) : this.expiredMs;
};
/**
* @param {?} originalKey
* @return {?}
*/
StorageService.prototype.computeKey = /**
* @param {?} originalKey
* @return {?}
*/
function (originalKey) {
return this.prefix + "__" + originalKey;
};
/**
* @param {?} obj
* @return {?}
*/
StorageService.prototype.isValidValue = /**
* @param {?} obj
* @return {?}
*/
function (obj) {
return (typeof obj === 'object' &&
obj !== null &&
typeof obj[EXPIRED_AT] === 'number');
};
/**
* @param {?} mills
* @return {?}
*/
StorageService.prototype.unExpired = /**
* @param {?} mills
* @return {?}
*/
function (mills) {
return mills === -1 || mills >= +new Date();
};
/**
* @param {?} action
* @param {?} actionArgs
* @return {?}
*/
StorageService.prototype.notifyAction = /**
* @param {?} action
* @param {?} actionArgs
* @return {?}
*/
function (action, actionArgs) {
if (this.actionNotify[action]) {
try {
this.actions.next(actionArgs);
}
catch (/** @type {?} */ e) {
this.errors.next({ code: 500, message: e.message });
}
}
};
return StorageService;
}());
var LocalStorageService = /** @class */ (function (_super) {
__extends(LocalStorageService, _super);
function LocalStorageService(config) {
return _super.call(this, StorageType.LOCAL, config) || this;
}
LocalStorageService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
LocalStorageService.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: Inject, args: [ANGULAR_WEB_STORE_CONFIG,] }] }
]; };
return LocalStorageService;
}(StorageService));
var SessionStorageService = /** @class */ (function (_super) {
__extends(SessionStorageService, _super);
function SessionStorageService(config) {
return _super.call(this, StorageType.SESSION, config) || this;
}
SessionStorageService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
SessionStorageService.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: Inject, args: [ANGULAR_WEB_STORE_CONFIG,] }] }
]; };
return SessionStorageService;
}(StorageService));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var AngularWebStoreModule = /** @class */ (function () {
function AngularWebStoreModule() {
}
/**
* @param {?=} config
* @return {?}
*/
AngularWebStoreModule.forRoot = /**
* @param {?=} config
* @return {?}
*/
function (config) {
if (config === void 0) { config = {}; }
return {
ngModule: AngularWebStoreModule,
providers: [{ provide: ANGULAR_WEB_STORE_CONFIG, useValue: config }]
};
};
AngularWebStoreModule.decorators = [
{ type: NgModule, args: [{
providers: [LocalStorageService, SessionStorageService]
},] },
];
return AngularWebStoreModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { AngularWebStoreModule, LocalStorageService, SessionStorageService };