src/lib/service/cache/app-cache.service.ts
The apps central caching service. It will provide the app with an easy to use cache that is aware of the platform it is running on. So it abstracts the platform-specific implementations of a cache from the application.
Properties |
|
Methods |
|
constructor(storage: StorageMap)
|
||||||
Parameters :
|
Public clear | ||||||||
clear(filter?: (undefined) => void)
|
||||||||
Deletes all items from local storage
Parameters :
Returns :
Observable<boolean>
Resolves true if clearing all items succeeded, false otherwise |
Public getItem | ||||||||
getItem(key: string)
|
||||||||
Get a stored item by its key.
Parameters :
Returns :
Observable<any>
The item's value if the key exists, null otherwise |
getStorage |
getStorage()
|
Returns :
Observable<any>
|
getStorageKeys |
getStorageKeys()
|
Returns :
Observable<any>
|
Public removeItem | ||||||||
removeItem(key: string)
|
||||||||
Removes an item from the storage.
Parameters :
Returns :
Observable<boolean>
Resolves true if removing the item succeeded, false otherwise |
replaceStorage | ||||||
replaceStorage(settings: any)
|
||||||
Parameters :
Returns :
void
|
Public setItem | ||||||||||||||||||||
setItem(key: string, value: any, debounce: number)
|
||||||||||||||||||||
Writes an item to the storage.
Parameters :
Returns :
Observable<boolean>
Resolves true if setting the item succeeded, false otherwise |
setStorage | ||||||
setStorage(options: any)
|
||||||
Parameters :
Returns :
Observable<any>
|
Public HOSTS |
HOSTS:
|
Type : string
|
Default value : 'eo.framework.cache.hosts'
|
Key for storing system definition |
Public LOCATION_HISTORY |
LOCATION_HISTORY:
|
Type : string
|
Default value : 'eo.framework.cache.locations.history'
|
Key for storing location history |
Public SYSTEM_DEFINITION |
SYSTEM_DEFINITION:
|
Type : string
|
Default value : 'eo.framework.cache.systemdefinition'
|
Key for storing system definition |
The apps central caching service. It will provide the app with an easy to use cache that is aware of the platform it is running on. So it abstracts the platform-specific implementations of a cache from the application.
import {Injectable} from '@angular/core';
import {Observable, Subject, of as observableOf, of, forkJoin, fromEvent} from 'rxjs';
import {StorageMap} from '@ngx-pwa/local-storage';
import {debounceTime, switchMap, map, first} from 'rxjs/operators';
import {Utils} from '../../util/utils';
/**
* The apps central caching service. It will provide the app with an easy to use cache that
* is aware of the platform it is running on. So it abstracts the platform-specific implementations
* of a cache from the application.
*/
@Injectable({
providedIn: 'root'
})
export class AppCacheService {
/**
* Key for storing system definition
*/
public SYSTEM_DEFINITION = 'eo.framework.cache.systemdefinition';
/**
* Key for storing system definition
*/
public HOSTS = 'eo.framework.cache.hosts';
/**
* Key for storing location history
*/
public LOCATION_HISTORY = 'eo.framework.cache.locations.history';
private itemsMap = new Map<string, Subject<any>>();
constructor(protected storage: StorageMap) {
// IndexedDB issue after update - refresh function (transform all wrapped items)
window['_ngStorageRefresh'] = () => this.getStorage().subscribe(storage => this.setStorage(storage).subscribe() && console.log(storage));
}
/**
* Writes an item to the storage.
* @param key The item's key
* @param value The value to be stored
* @param debounce The debounce time (default: 500) to reduce identical storage calls
* @returns Resolves true if setting the item succeeded, false otherwise
*/
public setItem(key: string, value: any, debounce: number = 500): Observable<boolean> {
if (!debounce) {
return this.storage.set(key, value);
} else {
if (!this.itemsMap.has(key)) {
const subject = new Subject();
subject.pipe(debounceTime(debounce), switchMap(val => this.storage.set(key, val))).subscribe();
this.itemsMap.set(key, subject);
}
this.itemsMap.get(key).next(value);
return observableOf(true);
}
}
/**
* Get a stored item by its key.
* @param key The item's key
* @returns The item's value if the key exists, null otherwise
*/
public getItem(key: string): Observable<any> {
return this.storage.get(key)
.pipe(map((item: any) => {
// IndexedDB issue after update (transform wrapped items)
return Object.keys(item || {}).join() === 'value' ? item.value : item;
}));
}
/**
* Removes an item from the storage.
* @param key The item's key
* @returns Resolves true if removing the item succeeded, false otherwise
*/
public removeItem(key: string): Observable<boolean> {
return this.storage.delete(key);
}
/**
* Deletes all items from local storage
* @param filter optional - Delete all keys that pass through filter
* @returns Resolves true if clearing all items succeeded, false otherwise
*/
public clear(filter?: (key) => boolean): Observable<boolean> {
return filter
? this.getStorageKeys().pipe(
switchMap((keys) => {
const list = keys.filter((k) => filter(k)).map((k) => this.removeItem(k));
return list.length ? forkJoin(list).pipe(map(() => true)) : of(true);
})
)
: this.storage.clear();
}
getStorageKeys(): Observable<any> {
return new Observable<string[]>((observer) => {
const keys = [];
this.storage.keys().subscribe({
next: (key) => keys.push(key),
complete: () => observer.next(keys)
});
}).pipe(first());
}
getStorage(): Observable<any> {
return this.getStorageKeys().pipe(
switchMap((keys) =>
keys.length
? forkJoin(
Utils.arrayToObject(
keys,
(o) => o,
(k) => this.getItem(k)
)
)
: of({})
)
);
}
setStorage(options: any): Observable<any> {
return forkJoin(Object.keys(options || {}).map((k) => this.setItem(k, options[k])));
}
replaceStorage(settings: any) {
for (const [key, value] of Object.entries(settings)) {
this.setItem(key, value);
}
}
}