mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
import { filter, take, distinctUntilChanged, first } from 'rxjs/operators';
|
|
import { Injectable } from '@angular/core';
|
|
import { MemoizedSelector, select, Store } from '@ngrx/store';
|
|
|
|
import { Observable } from 'rxjs';
|
|
|
|
import { ResponseCacheEntry } from './response-cache.reducer';
|
|
import { hasNoValue } from '../../shared/empty.util';
|
|
import { ResponseCacheRemoveAction, ResponseCacheAddAction } from './response-cache.actions';
|
|
import { RestResponse } from './response-cache.models';
|
|
import { coreSelector, CoreState } from '../core.reducers';
|
|
import { pathSelector } from '../shared/selectors';
|
|
|
|
function entryFromKeySelector(key: string): MemoizedSelector<CoreState, ResponseCacheEntry> {
|
|
return pathSelector<CoreState, ResponseCacheEntry>(coreSelector, 'cache/response', key);
|
|
}
|
|
|
|
/**
|
|
* A service to interact with the response cache
|
|
*/
|
|
@Injectable()
|
|
export class ResponseCacheService {
|
|
constructor(
|
|
private store: Store<CoreState>
|
|
) {
|
|
}
|
|
|
|
add(key: string, response: RestResponse, msToLive: number): Observable<ResponseCacheEntry> {
|
|
if (!this.has(key)) {
|
|
this.store.dispatch(new ResponseCacheAddAction(key, response, new Date().getTime(), msToLive));
|
|
}
|
|
return this.get(key);
|
|
}
|
|
|
|
/**
|
|
* Get an observable of the response with the specified key
|
|
*
|
|
* @param key
|
|
* the key of the response to get
|
|
* @return Observable<ResponseCacheEntry>
|
|
* an observable of the ResponseCacheEntry with the specified key
|
|
*/
|
|
get(key: string): Observable<ResponseCacheEntry> {
|
|
return this.store.pipe(
|
|
select(entryFromKeySelector(key)),
|
|
filter((entry: ResponseCacheEntry) => this.isValid(entry)),
|
|
distinctUntilChanged()
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Check whether the response with the specified key is cached
|
|
*
|
|
* @param key
|
|
* the key of the response to check
|
|
* @return boolean
|
|
* true if the response with the specified key is cached,
|
|
* false otherwise
|
|
*/
|
|
has(key: string): boolean {
|
|
let result: boolean;
|
|
|
|
this.store.pipe(select(entryFromKeySelector(key)),
|
|
first()
|
|
).subscribe((entry: ResponseCacheEntry) => {
|
|
result = this.isValid(entry);
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
remove(key: string): void {
|
|
if (this.has(key)) {
|
|
this.store.dispatch(new ResponseCacheRemoveAction(key));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check whether a ResponseCacheEntry 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: ResponseCacheEntry): boolean {
|
|
if (hasNoValue(entry)) {
|
|
return false;
|
|
} else {
|
|
const timeOutdated = entry.timeAdded + entry.msToLive;
|
|
const isOutDated = new Date().getTime() > timeOutdated;
|
|
if (isOutDated) {
|
|
this.store.dispatch(new ResponseCacheRemoveAction(entry.key));
|
|
}
|
|
return !isOutDated;
|
|
}
|
|
}
|
|
|
|
}
|