text: /**
   * @license ng-alain(cipchk@qq.com) v1.0.0-beta.10
   * (c) 2018 Cipchk http://ng-alain.com/
   * License: MIT
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('date-fns/add_seconds'), require('rxjs/Observable'), require('rxjs/observable/of'), require('rxjs/operators'), require('rxjs/BehaviorSubject')) :
  	typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular/common/http', 'date-fns/add_seconds', 'rxjs/Observable', 'rxjs/observable/of', 'rxjs/operators', 'rxjs/BehaviorSubject'], factory) :
  	(factory((global.delon = global.delon || {}, global.delon.cache = {}),global.ng.core,global.ng.common.http,global['date-fns/add_seconds/index'],global.Rx,global.Rx.Observable,global.Rx.Observable.prototype,global.Rx));
  }(this, (function (exports,core,http,addSeconds,Observable,of,operators,BehaviorSubject) { 'use strict';
  
  addSeconds = addSeconds && addSeconds.hasOwnProperty('default') ? addSeconds['default'] : addSeconds;
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @record
   */
  
  var DC_STORE_STORAGE_TOKEN = new core.InjectionToken('DC_STORE_STORAGE_TOKEN');
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  var DelonCacheConfig = /** @class */ (function () {
      function DelonCacheConfig() {
          /**
           * 缓存模式，默认：`promise`
           * - `promise` 约定模式，允许 `key` 作为 http 获取数据
           * - `none` 正常模式
           */
          this.mode = 'promise';
          /**
           * 重命名返回参数，例如：
           * - `null` 返回体为内容
           * - `list` 返回体应 `{ list: [] }`
           * - `result.list` 返回体应 `{ result: { list: [] } }`
           */
          this.reName = '';
          /**
           * 持久化数据键值前缀
           */
          this.prefix = '';
          /**
           * 持久化数据元数据存储键名
           */
          this.meta_key = '__cache_meta';
      }
      DelonCacheConfig.decorators = [
          { type: core.Injectable },
      ];
      return DelonCacheConfig;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  var CacheService = /** @class */ (function () {
      function CacheService(options, store, http$$1) {
          this.options = options;
          this.store = store;
          this.http = http$$1;
          this.memory = new Map();
          this.notifyBuffer = new Map();
          this.meta = new Set();
          this.freq_tick = 3000;
          this.loadMeta();
          this.startExpireNotify();
      }
      /**
       * @param {?} obj
       * @param {?} path
       * @param {?=} defaultValue
       * @return {?}
       */
      CacheService.prototype._deepGet = /**
       * @param {?} obj
       * @param {?} path
       * @param {?=} defaultValue
       * @return {?}
       */
      function (obj, path, defaultValue) {
          if (!obj)
              return defaultValue;
          if (path.length <= 1) {
              var /** @type {?} */ checkObj = path.length ? obj[path[0]] : obj;
              return typeof checkObj === 'undefined' ? defaultValue : checkObj;
          }
          return path.reduce(function (o, k) { return o[k]; }, obj) || defaultValue;
      };
      /**
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.pushMeta = /**
       * @param {?} key
       * @return {?}
       */
      function (key) {
          if (this.meta.has(key))
              return;
          this.meta.add(key);
          this.saveMeta();
      };
      /**
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.removeMeta = /**
       * @param {?} key
       * @return {?}
       */
      function (key) {
          if (!this.meta.has(key))
              return;
          this.meta.delete(key);
          this.saveMeta();
      };
      /**
       * @return {?}
       */
      CacheService.prototype.loadMeta = /**
       * @return {?}
       */
      function () {
          var _this = this;
          var /** @type {?} */ ret = this.store.get(this.options.meta_key);
          if (ret && ret.v) {
              (/** @type {?} */ (ret.v)).forEach(function (key) { return _this.meta.add(key); });
          }
      };
      /**
       * @return {?}
       */
      CacheService.prototype.saveMeta = /**
       * @return {?}
       */
      function () {
          var /** @type {?} */ metaData = [];
          this.meta.forEach(function (key) { return metaData.push(key); });
          this.store.set(this.options.meta_key, { v: metaData, e: 0 });
      };
      /**
       * @return {?}
       */
      CacheService.prototype.getMeta = /**
       * @return {?}
       */
      function () {
          return this.meta;
      };
      /**
       * 缓存对象
       */
      /**
       * 缓存对象
       * @param {?} key
       * @param {?} data
       * @param {?=} options
       * @return {?}
       */
      CacheService.prototype.set = /**
       * 缓存对象
       * @param {?} key
       * @param {?} data
       * @param {?=} options
       * @return {?}
       */
      function (key, data, options) {
          var _this = this;
          if (options === void 0) { options = {}; }
          // expire
          var /** @type {?} */ e = 0;
          if (options.expire) {
              e = addSeconds(new Date(), options.expire).valueOf();
          }
          if (!(data instanceof Observable.Observable)) {
              this.save(options.type, key, { v: data, e: e });
              return;
          }
          return data.pipe(operators.tap(function (v) {
              _this.save(options.type, key, { v: v, e: e });
          }));
      };
      /**
       * @param {?} type
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      CacheService.prototype.save = /**
       * @param {?} type
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      function (type, key, value) {
          if (type === 'm') {
              this.memory.set(key, value);
          }
          else {
              this.store.set(this.options.prefix + key, value);
              this.pushMeta(key);
          }
          this.runNotify(key, 'set');
      };
      /**
       * @param {?} key
       * @param {?=} options
       * @return {?}
       */
      CacheService.prototype.get = /**
       * @param {?} key
       * @param {?=} options
       * @return {?}
       */
      function (key, options) {
          var _this = this;
          if (options === void 0) { options = {}; }
          var /** @type {?} */ isPromise = options.mode !== 'none' && this.options.mode === 'promise';
          var /** @type {?} */ value = this.memory.has(key)
              ? this.memory.get(key)
              : this.store.get(this.options.prefix + key);
          if (!value || (value.e && value.e > 0 && value.e < new Date().valueOf())) {
              if (isPromise) {
                  return this.http
                      .get(key)
                      .pipe(operators.map(function (ret) {
                      return _this._deepGet(ret, /** @type {?} */ (_this.options.reName), null);
                  }), operators.tap(function (v) { return _this.set(key, v); }));
              }
              return null;
          }
          return isPromise ? of.of(value.v) : value.v;
      };
      /** 获取缓存数据，若 `key` 不存在或已过期则返回 null */
      /**
       * 获取缓存数据，若 `key` 不存在或已过期则返回 null
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.getNone = /**
       * 获取缓存数据，若 `key` 不存在或已过期则返回 null
       * @param {?} key
       * @return {?}
       */
      function (key) {
          return this.get(key, { mode: 'none' });
      };
      /**
       * 获取缓存，若不存在则设置缓存对象
       */
      /**
       * 获取缓存，若不存在则设置缓存对象
       * @param {?} key
       * @param {?} data
       * @param {?=} options
       * @return {?}
       */
      CacheService.prototype.tryGet = /**
       * 获取缓存，若不存在则设置缓存对象
       * @param {?} key
       * @param {?} data
       * @param {?=} options
       * @return {?}
       */
      function (key, data, options) {
          if (options === void 0) { options = {}; }
          var /** @type {?} */ ret = this.getNone(key);
          if (ret === null) {
              if (!(data instanceof Observable.Observable)) {
                  this.set(key, data, /** @type {?} */ (options));
                  return data;
              }
              return this.set(key, /** @type {?} */ (data), /** @type {?} */ (options));
          }
          return of.of(ret);
      };
      // endregion
      // region: has
      /** 是否缓存 `key` */
      /**
       * 是否缓存 `key`
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.has = /**
       * 是否缓存 `key`
       * @param {?} key
       * @return {?}
       */
      function (key) {
          return this.memory.has(key) || this.meta.has(key);
      };
      /**
       * @param {?} key
       * @param {?} needNotify
       * @return {?}
       */
      CacheService.prototype._remove = /**
       * @param {?} key
       * @param {?} needNotify
       * @return {?}
       */
      function (key, needNotify) {
          if (needNotify)
              this.runNotify(key, 'remove');
          if (this.memory.has(key)) {
              this.memory.delete(key);
              return;
          }
          this.store.remove(this.options.prefix + key);
          this.removeMeta(key);
      };
      /** 移除缓存 */
      /**
       * 移除缓存
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.remove = /**
       * 移除缓存
       * @param {?} key
       * @return {?}
       */
      function (key) {
          this._remove(key, true);
      };
      /** 清空所有缓存 */
      /**
       * 清空所有缓存
       * @return {?}
       */
      CacheService.prototype.clear = /**
       * 清空所有缓存
       * @return {?}
       */
      function () {
          var _this = this;
          this.notifyBuffer.forEach(function (v, k) { return _this.runNotify(k, 'remove'); });
          this.memory.clear();
          this.meta.forEach(function (key) { return _this.store.remove(_this.options.prefix + key); });
      };
      Object.defineProperty(CacheService.prototype, "freq", {
          // endregion
          // region: notify
          /**
           * 设置监听频率，单位：毫秒且最低 `20ms`，默认：`3000ms`
           */
          set: /**
           * 设置监听频率，单位：毫秒且最低 `20ms`，默认：`3000ms`
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this.freq_tick = Math.max(20, value);
              this.abortExpireNotify();
              this.startExpireNotify();
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      CacheService.prototype.startExpireNotify = /**
       * @return {?}
       */
      function () {
          this.checkExpireNotify();
          this.runExpireNotify();
      };
      /**
       * @return {?}
       */
      CacheService.prototype.runExpireNotify = /**
       * @return {?}
       */
      function () {
          var _this = this;
          this.freq_time = setTimeout(function () {
              _this.checkExpireNotify();
              _this.runExpireNotify();
          }, this.freq_tick);
      };
      /**
       * @return {?}
       */
      CacheService.prototype.checkExpireNotify = /**
       * @return {?}
       */
      function () {
          var _this = this;
          var /** @type {?} */ removed = [];
          this.notifyBuffer.forEach(function (v, key) {
              if (_this.has(key) && _this.getNone(key) === null)
                  removed.push(key);
          });
          removed.forEach(function (key) {
              _this.runNotify(key, 'expire');
              _this._remove(key, false);
          });
      };
      /**
       * @return {?}
       */
      CacheService.prototype.abortExpireNotify = /**
       * @return {?}
       */
      function () {
          clearTimeout(this.freq_time);
      };
      /**
       * @param {?} key
       * @param {?} type
       * @return {?}
       */
      CacheService.prototype.runNotify = /**
       * @param {?} key
       * @param {?} type
       * @return {?}
       */
      function (key, type) {
          if (!this.notifyBuffer.has(key))
              return;
          this.notifyBuffer.get(key).next({ type: type, value: this.getNone(key) });
      };
      /**
       * `key` 监听，当 `key` 变更、过期、移除时通知，注意以下若干细节：
       *
       * - 调用后除再次调用 `cancelNotify` 否则永远不过期
       * - 监听器每 `freq` (默认：3秒) 执行一次过期检查
       */
      /**
       * `key` 监听，当 `key` 变更、过期、移除时通知，注意以下若干细节：
       *
       * - 调用后除再次调用 `cancelNotify` 否则永远不过期
       * - 监听器每 `freq` (默认：3秒) 执行一次过期检查
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.notify = /**
       * `key` 监听，当 `key` 变更、过期、移除时通知，注意以下若干细节：
       *
       * - 调用后除再次调用 `cancelNotify` 否则永远不过期
       * - 监听器每 `freq` (默认：3秒) 执行一次过期检查
       * @param {?} key
       * @return {?}
       */
      function (key) {
          if (!this.notifyBuffer.has(key)) {
              var /** @type {?} */ change$ = new BehaviorSubject.BehaviorSubject(this.getNone(key));
              this.notifyBuffer.set(key, change$);
          }
          return this.notifyBuffer.get(key).asObservable();
      };
      /**
       * 取消 `key` 监听
       */
      /**
       * 取消 `key` 监听
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.cancelNotify = /**
       * 取消 `key` 监听
       * @param {?} key
       * @return {?}
       */
      function (key) {
          if (!this.notifyBuffer.has(key))
              return;
          this.notifyBuffer.get(key).unsubscribe();
          this.notifyBuffer.delete(key);
      };
      /** `key` 是否已经监听 */
      /**
       * `key` 是否已经监听
       * @param {?} key
       * @return {?}
       */
      CacheService.prototype.hasNotify = /**
       * `key` 是否已经监听
       * @param {?} key
       * @return {?}
       */
      function (key) {
          return this.notifyBuffer.has(key);
      };
      /** 清空所有 `key` 的监听 */
      /**
       * 清空所有 `key` 的监听
       * @return {?}
       */
      CacheService.prototype.clearNotify = /**
       * 清空所有 `key` 的监听
       * @return {?}
       */
      function () {
          this.notifyBuffer.forEach(function (v) { return v.unsubscribe(); });
          this.notifyBuffer.clear();
      };
      // endregion
      /**
       * @return {?}
       */
      CacheService.prototype.ngOnDestroy = /**
       * @return {?}
       */
      function () {
          this.memory.clear();
          this.abortExpireNotify();
          this.clearNotify();
      };
      CacheService.decorators = [
          { type: core.Injectable },
      ];
      /** @nocollapse */
      CacheService.ctorParameters = function () { return [
          { type: DelonCacheConfig, },
          { type: undefined, decorators: [{ type: core.Inject, args: [DC_STORE_STORAGE_TOKEN,] },] },
          { type: http.HttpClient, },
      ]; };
      return CacheService;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  var LocalStorageCacheService = /** @class */ (function () {
      function LocalStorageCacheService() {
      }
      /**
       * @param {?} key
       * @return {?}
       */
      LocalStorageCacheService.prototype.get = /**
       * @param {?} key
       * @return {?}
       */
      function (key) {
          return JSON.parse(localStorage.getItem(key) || 'null') || null;
      };
      /**
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      LocalStorageCacheService.prototype.set = /**
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      function (key, value) {
          localStorage.setItem(key, JSON.stringify(value));
          return true;
      };
      /**
       * @param {?} key
       * @return {?}
       */
      LocalStorageCacheService.prototype.remove = /**
       * @param {?} key
       * @return {?}
       */
      function (key) {
          localStorage.removeItem(key);
      };
      return LocalStorageCacheService;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  var DelonCacheModule = /** @class */ (function () {
      function DelonCacheModule() {
      }
      /**
       * @param {?=} options
       * @return {?}
       */
      DelonCacheModule.forRoot = /**
       * @param {?=} options
       * @return {?}
       */
      function (options) {
          return {
              ngModule: DelonCacheModule,
              providers: [
                  DelonCacheConfig,
                  CacheService,
                  { provide: DC_STORE_STORAGE_TOKEN, useClass: LocalStorageCacheService },
              ],
          };
      };
      DelonCacheModule.decorators = [
          { type: core.NgModule, args: [{},] },
      ];
      return DelonCacheModule;
  }());
  
  exports.DC_STORE_STORAGE_TOKEN = DC_STORE_STORAGE_TOKEN;
  exports.CacheService = CacheService;
  exports.DelonCacheModule = DelonCacheModule;
  exports.ɵa = DelonCacheConfig;
  exports.ɵb = LocalStorageCacheService;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=cache.umd.js.map
  