ObjectCacheService docs & tests

This commit is contained in:
Art Lowel
2017-03-08 12:57:03 +01:00
parent f1bf3e4062
commit 0e516beabd
3 changed files with 194 additions and 6 deletions

View File

@@ -6,33 +6,93 @@ import { Observable } from "rxjs";
import { hasNoValue } from "../../shared/empty.util";
import { GenericConstructor } from "../shared/generic-constructor";
/**
* A service to interact with the object cache
*/
@Injectable()
export class ObjectCacheService {
constructor(
private store: Store<ObjectCacheState>
) {}
/**
* Add an object to the cache
*
* @param objectToCache
* The object to add
* @param msToLive
* The number of milliseconds it should be cached for
*/
add(objectToCache: CacheableObject, msToLive: number): void {
this.store.dispatch(new AddToObjectCacheAction(objectToCache, new Date().getTime(), msToLive));
}
/**
* Remove the object with the supplied UUID from the cache
*
* @param uuid
* The UUID of the object to be removed
*/
remove(uuid: string): void {
this.store.dispatch(new RemoveFromObjectCacheAction(uuid));
}
get<T extends CacheableObject>(uuid: string, ctor: GenericConstructor<T>): Observable<T> {
/**
* Get an observable of the object with the specified UUID
*
* The type needs to be specified as well, in order to turn
* the cached plain javascript object in to an instance of
* a class.
*
* e.g. get('c96588c6-72d3-425d-9d47-fa896255a695', Item)
*
* @param uuid
* The UUID of the object to get
* @param type
* The type of the object to get
* @return Observable<T>
*/
get<T extends CacheableObject>(uuid: string, type: GenericConstructor<T>): Observable<T> {
return this.store.select<ObjectCacheEntry>('core', 'cache', 'object', uuid)
.filter(entry => this.isValid(entry))
.distinctUntilChanged()
.map((entry: ObjectCacheEntry) => <T> Object.assign(new ctor(), entry.data));
.map((entry: ObjectCacheEntry) => <T> Object.assign(new type(), entry.data));
}
getList<T extends CacheableObject>(uuids: Array<string>, ctor: GenericConstructor<T>): Observable<Array<T>> {
/**
* Get an observable for an array of objects of the same type
* with the specified UUIDs
*
* The type needs to be specified as well, in order to turn
* the cached plain javascript object in to an instance of
* a class.
*
* e.g. getList([
* 'c96588c6-72d3-425d-9d47-fa896255a695',
* 'cff860da-cf5f-4fda-b8c9-afb7ec0b2d9e'
* ], Collection)
*
* @param uuids
* An array of UUIDs of the objects to get
* @param type
* The type of the objects to get
* @return Observable<Array<T>>
*/
getList<T extends CacheableObject>(uuids: Array<string>, type: GenericConstructor<T>): Observable<Array<T>> {
return Observable.combineLatest(
uuids.map((id: string) => this.get<T>(id, ctor))
uuids.map((id: string) => this.get<T>(id, type))
);
}
/**
* Check whether the object with the specified UUID is cached
*
* @param uuid
* The UUID of the object to check
* @return boolean
* true if the object with the specified UUID is cached,
* false otherwise
*/
has(uuid: string): boolean {
let result: boolean;
@@ -43,6 +103,15 @@ export class ObjectCacheService {
return result;
}
/**
* Check whether an ObjectCacheEntry should still be cached
*
* @param entry
* the entry to check
* @return boolean
* false if the entry is null, undefined, or its time to
* live has been exceeded, true otherwise
*/
private isValid(entry: ObjectCacheEntry): boolean {
if (hasNoValue(entry)) {
return false;