All files / utils/services/events ngx-events-layer.layer.ts

6.78% Statements 4/59
0% Branches 0/24
0% Functions 0/22
7.69% Lines 4/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122  8x 8x     8x       8x                                                                                                                                                                                                                                
import { CacheLayerInterface, CacheServiceConfigInterface } from './ngx-events-layer.interfaces';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
 
const FRIENDLY_ERROR_MESSAGES = {
  MISSING_OBSERVABLE_ITEM: `is missing from the layer misspelled name ? as soon as you provide correct name value will be emitted!`
};
 
export class CacheLayer<T> {
 
  public items: BehaviorSubject<Array<T>> = new BehaviorSubject([]);
  public name: string;
  public config: CacheServiceConfigInterface;
  private map: Map<any, any> = new Map();
  static createCacheParams(config) {
    if (config.params.constructor === Object) {
      return; // Todo
    } else if (config.constructor === String) {
      return; // Todo
    } else if (config.params.constructor === Number) {
      return; // Todo
    } else if (config.params.constructor === Array) {
      return; // Todo
    }
  }
 
  public get(name): T {
    return this.map.get(name);
  }
 
  constructor(layer: CacheLayerInterface) {
    this.name = layer.name;
    this.config = layer.config;
    if (this.config.localStorage) {
      layer.items.forEach(item => this.map.set(item['key'], item));
      if (layer.items.constructor === BehaviorSubject) {
        layer.items = layer.items.getValue() || [];
      }
      this.items.next([...this.items.getValue(), ...layer.items]);
    }
    this.initHook(layer);
  }
 
  private initHook(layer) {
    if (this.config.maxAge) {
      this.onExpireAll(layer);
    }
  }
 
  private onExpireAll(layer) {
    layer.items.forEach(item => this.onExpire(item['key']));
  }
 
  private putItemHook(layerItem): void {
    if (this.config.maxAge) {
      this.onExpire(layerItem['key']);
    }
  }
 
  public getItem(key: string): T {
    if (this.map.has(key)) {
      return this.get(key);
    } else {
      return null;
    }
  }
 
  public putItem(layerItem: T): T {
    this.map.set(layerItem['key'], layerItem);
    const item = this.get(layerItem['key']);
    const filteredItems = this.items.getValue().filter(item => item['key'] !== layerItem['key']);
    if (this.config.localStorage) {
      localStorage.setItem(this.name, JSON.stringify(<CacheLayerInterface>{
        config: this.config,
        name: this.name,
        items: [...filteredItems, item]
      }));
    }
 
    this.items.next([...filteredItems, item]);
    this.putItemHook(layerItem);
    return layerItem;
  }
 
  private onExpire(key: string): void {
    Observable
      .create(observer => observer.next())
      .timeoutWith(this.config.maxAge, Observable.of(1))
      .skip(1)
      .subscribe(observer => this.removeItem(key));
  }
 
  public removeItem(key: string): void {
    const newLayerItems = this.items.getValue().filter(item => item['key'] !== key);
    if (this.config.localStorage) {
      const newLayer = <CacheLayerInterface>{
        config: this.config,
        name: this.name,
        items: newLayerItems
      };
      localStorage.setItem(this.name, JSON.stringify(newLayer));
    }
    this.map.delete(key);
    this.items.next(newLayerItems);
  }
 
  public getItemObservable(key: string): Observable<T> {
    return this.items.asObservable().filter(() => this.map.has(key)).map(res => res[0]);
  }
 
  public flushCache(): Observable<boolean> {
    return this.items.asObservable()
      .map(items => {
        items.forEach(i => this.removeItem(i['key']));
        return true;
      });
  }
 
}
 
// console.log(Array.from(this.keys()))