forked from hazza/dspace-angular
Removed the handle index (not needed because the uuid index will always be used internally) and all associated code.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { LookupGuard } from './lookup-guard';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { IdentifierType } from '../core/index/index.reducer';
|
||||
import { IdentifierType } from '../core/data/request.models';
|
||||
|
||||
describe('LookupGuard', () => {
|
||||
let dsoService: any;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IdentifierType } from '../core/index/index.reducer';
|
||||
import { IdentifierType } from '../core/data/request.models';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
|
9
src/app/core/cache/object-cache.service.ts
vendored
9
src/app/core/cache/object-cache.service.ts
vendored
@@ -21,7 +21,6 @@ import {
|
||||
import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer';
|
||||
import { AddToSSBAction } from './server-sync-buffer.actions';
|
||||
import { getMapsToType } from './builders/build-decorators';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
|
||||
/**
|
||||
* The base selector function to select the object cache in the store
|
||||
@@ -81,10 +80,10 @@ export class ObjectCacheService {
|
||||
* @return Observable<NormalizedObject<T>>
|
||||
* An observable of the requested object in normalized form
|
||||
*/
|
||||
getObjectByID<T extends CacheableObject>(id: string, identifierType: IdentifierType = IdentifierType.UUID):
|
||||
getObjectByID<T extends CacheableObject>(id: string):
|
||||
Observable<NormalizedObject<T>> {
|
||||
return this.store.pipe(
|
||||
select(selfLinkFromUuidSelector(id, identifierType)),
|
||||
select(selfLinkFromUuidSelector(id)),
|
||||
mergeMap((selfLink: string) => this.getObjectBySelfLink(selfLink)
|
||||
)
|
||||
)
|
||||
@@ -196,11 +195,11 @@ export class ObjectCacheService {
|
||||
* true if the object with the specified UUID is cached,
|
||||
* false otherwise
|
||||
*/
|
||||
hasById(id: string, identifierType: IdentifierType = IdentifierType.UUID): boolean {
|
||||
hasById(id: string): boolean {
|
||||
let result: boolean;
|
||||
|
||||
this.store.pipe(
|
||||
select(selfLinkFromUuidSelector(id, identifierType)),
|
||||
select(selfLinkFromUuidSelector(id)),
|
||||
take(1)
|
||||
).subscribe((selfLink: string) => result = this.hasBySelfLink(selfLink));
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ObjectCacheEffects } from './cache/object-cache.effects';
|
||||
import { IdentifierIndexEffects } from './index/index.effects';
|
||||
import { UUIDIndexEffects } from './index/index.effects';
|
||||
import { RequestEffects } from './data/request.effects';
|
||||
import { AuthEffects } from './auth/auth.effects';
|
||||
import { JsonPatchOperationsEffects } from './json-patch/json-patch-operations.effects';
|
||||
@@ -10,7 +10,7 @@ import { RouteEffects } from './services/route.effects';
|
||||
export const coreEffects = [
|
||||
RequestEffects,
|
||||
ObjectCacheEffects,
|
||||
IdentifierIndexEffects,
|
||||
UUIDIndexEffects,
|
||||
AuthEffects,
|
||||
JsonPatchOperationsEffects,
|
||||
ServerSyncBufferEffects,
|
||||
|
@@ -37,7 +37,6 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
|
||||
import { ChangeAnalyzer } from './change-analyzer';
|
||||
import { RestRequestMethod } from './rest-request-method';
|
||||
import { getMapsToType } from '../cache/builders/build-decorators';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
|
||||
export abstract class DataService<T extends CacheableObject> {
|
||||
protected abstract requestService: RequestService;
|
||||
@@ -147,19 +146,15 @@ export abstract class DataService<T extends CacheableObject> {
|
||||
return `${endpoint}/${resourceID}`;
|
||||
}
|
||||
|
||||
findById(id: string, identifierType: IdentifierType = IdentifierType.UUID): Observable<RemoteData<T>> {
|
||||
let hrefObs;
|
||||
if (identifierType === IdentifierType.UUID) {
|
||||
hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
map((endpoint: string) => this.getIDHref(endpoint, id)));
|
||||
} else if (identifierType === IdentifierType.HANDLE) {
|
||||
hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
map((endpoint: string) => this.getIDHref(endpoint, encodeURIComponent(id))));
|
||||
}
|
||||
findById(id: string): Observable<RemoteData<T>> {
|
||||
|
||||
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
map((endpoint: string) => this.getIDHref(endpoint, encodeURIComponent(id))))
|
||||
|
||||
hrefObs.pipe(
|
||||
find((href: string) => hasValue(href)))
|
||||
.subscribe((href: string) => {
|
||||
const request = new FindByIDRequest(this.requestService.generateRequestId(), href, id, identifierType);
|
||||
const request = new FindByIDRequest(this.requestService.generateRequestId(), href, id);
|
||||
this.requestService.configure(request, this.forceBypassCache);
|
||||
});
|
||||
|
||||
|
@@ -2,13 +2,12 @@ import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { FindByIDRequest, IdentifierType } from './request.models';
|
||||
import { RequestService } from './request.service';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
import { DsoRedirectDataService } from './dso-redirect-data.service';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CoreState } from '../core.reducers';
|
||||
@@ -111,7 +110,7 @@ describe('DsoRedirectDataService', () => {
|
||||
scheduler.schedule(() => service.findById(dsoUUID, IdentifierType.UUID));
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestUUIDURL, dsoUUID, IdentifierType.UUID), false);
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestUUIDURL, dsoUUID), false);
|
||||
});
|
||||
|
||||
it('should configure the proper FindByIDRequest for handle', () => {
|
||||
@@ -119,7 +118,7 @@ describe('DsoRedirectDataService', () => {
|
||||
scheduler.schedule(() => service.findById(dsoHandle, IdentifierType.HANDLE));
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestHandleURL, dsoHandle, IdentifierType.HANDLE), false);
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestHandleURL, dsoHandle), false);
|
||||
});
|
||||
|
||||
it('should navigate to item route', () => {
|
||||
|
@@ -8,9 +8,8 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv
|
||||
import { RequestService } from './request.service';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { FindAllOptions, FindByIDRequest } from './request.models';
|
||||
import { FindAllOptions, FindByIDRequest, IdentifierType } from './request.models';
|
||||
import { Observable } from 'rxjs';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
import { RemoteData } from './remote-data';
|
||||
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
@@ -61,7 +60,7 @@ export class DsoRedirectDataService extends DataService<any> {
|
||||
|
||||
findById(id: string, identifierType = IdentifierType.UUID): Observable<RemoteData<FindByIDRequest>> {
|
||||
this.setLinkPath(identifierType);
|
||||
return super.findById(id, identifierType).pipe(
|
||||
return super.findById(id).pipe(
|
||||
getFinishedRemoteData(),
|
||||
take(1),
|
||||
tap((response) => {
|
||||
|
@@ -10,7 +10,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
|
||||
describe('DSpaceObjectDataService', () => {
|
||||
let scheduler: TestScheduler;
|
||||
@@ -73,7 +72,7 @@ describe('DSpaceObjectDataService', () => {
|
||||
scheduler.schedule(() => service.findById(testObject.uuid));
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestURL, testObject.uuid, IdentifierType.UUID), false);
|
||||
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestURL, testObject.uuid), false);
|
||||
});
|
||||
|
||||
it('should return a RemoteData<DSpaceObject> for the object with the given ID', () => {
|
||||
|
@@ -19,10 +19,15 @@ import { MetadatafieldParsingService } from './metadatafield-parsing.service';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
|
||||
import { MappedCollectionsReponseParsingService } from './mapped-collections-reponse-parsing.service';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
|
||||
// uuid and handle requests have separate endpoints
|
||||
export enum IdentifierType {
|
||||
UUID ='uuid',
|
||||
HANDLE = 'handle'
|
||||
}
|
||||
|
||||
export abstract class RestRequest {
|
||||
public responseMsToLive = 0;
|
||||
constructor(
|
||||
@@ -126,8 +131,7 @@ export class FindByIDRequest extends GetRequest {
|
||||
constructor(
|
||||
uuid: string,
|
||||
href: string,
|
||||
public resourceID: string,
|
||||
public identifierType?: IdentifierType
|
||||
public resourceID: string
|
||||
) {
|
||||
super(uuid, href);
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ import { UUIDService } from '../shared/uuid.service';
|
||||
import { RequestConfigureAction, RequestExecuteAction } from './request.actions';
|
||||
import {
|
||||
DeleteRequest,
|
||||
FindByIDRequest,
|
||||
GetRequest,
|
||||
HeadRequest,
|
||||
OptionsRequest,
|
||||
@@ -22,7 +21,6 @@ import {
|
||||
} from './request.models';
|
||||
import { RequestService } from './request.service';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { IdentifierType } from '../index/index.reducer';
|
||||
|
||||
describe('RequestService', () => {
|
||||
let scheduler: TestScheduler;
|
||||
@@ -40,7 +38,6 @@ describe('RequestService', () => {
|
||||
const testDeleteRequest = new DeleteRequest(testUUID, testHref);
|
||||
const testOptionsRequest = new OptionsRequest(testUUID, testHref);
|
||||
const testHeadRequest = new HeadRequest(testUUID, testHref);
|
||||
const testFindByIdRequest = new FindByIDRequest(testUUID, testHref, testUUID, IdentifierType.UUID);
|
||||
const testPatchRequest = new PatchRequest(testUUID, testHref);
|
||||
let selectSpy;
|
||||
|
||||
@@ -309,14 +306,6 @@ describe('RequestService', () => {
|
||||
const result = serviceAsAny.isCachedOrPending(testGetRequest);
|
||||
const expected = true;
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
it('should return true for instance of FindByIdRequest', () => {
|
||||
(objectCache.hasBySelfLink as any).and.returnValue(false);
|
||||
const result = serviceAsAny.isCachedOrPending(testFindByIdRequest);
|
||||
expect(objectCache.hasById).toHaveBeenCalledWith(testUUID, IdentifierType.UUID);
|
||||
const expected = true;
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
@@ -11,7 +11,7 @@ import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { IdentifierType, IndexState, MetaIndexState, REQUEST, UUID_MAPPING } from '../index/index.reducer';
|
||||
import { IndexName, IndexState, MetaIndexState } from '../index/index.reducer';
|
||||
import {
|
||||
originalRequestUUIDFromRequestUUIDSelector,
|
||||
requestIndexSelector,
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from '../index/index.selectors';
|
||||
import { UUIDService } from '../shared/uuid.service';
|
||||
import { RequestConfigureAction, RequestExecuteAction, RequestRemoveAction } from './request.actions';
|
||||
import { FindByIDRequest, GetRequest, RestRequest } from './request.models';
|
||||
import { GetRequest, RestRequest } from './request.models';
|
||||
import { RequestEntry, RequestState } from './request.reducer';
|
||||
import { CommitSSBAction } from '../cache/server-sync-buffer.actions';
|
||||
import { RestRequestMethod } from './rest-request-method';
|
||||
@@ -162,7 +162,7 @@ export class RequestService {
|
||||
filter((entry) => hasValue(entry)),
|
||||
take(1)
|
||||
).subscribe((entry) => {
|
||||
return this.store.dispatch(new AddToIndexAction(UUID_MAPPING, request.uuid, entry.request.uuid))
|
||||
return this.store.dispatch(new AddToIndexAction(IndexName.UUID_MAPPING, request.uuid, entry.request.uuid))
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -206,7 +206,7 @@ export class RequestService {
|
||||
}
|
||||
});
|
||||
this.requestsOnTheirWayToTheStore = this.requestsOnTheirWayToTheStore.filter((reqHref: string) => reqHref.indexOf(href) < 0);
|
||||
this.indexStore.dispatch(new RemoveFromIndexBySubstringAction(REQUEST, href));
|
||||
this.indexStore.dispatch(new RemoveFromIndexBySubstringAction(IndexName.REQUEST, href));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,14 +225,7 @@ export class RequestService {
|
||||
private isCachedOrPending(request: GetRequest): boolean {
|
||||
const inReqCache = this.hasByHref(request.href);
|
||||
const inObjCache = this.objectCache.hasBySelfLink(request.href);
|
||||
let inObjIdCache = false;
|
||||
if (request instanceof FindByIDRequest) {
|
||||
const req = request as FindByIDRequest;
|
||||
if (hasValue(req.identifierType && hasValue(req.resourceID))) {
|
||||
inObjIdCache = this.objectCache.hasById(req.resourceID, req.identifierType)
|
||||
}
|
||||
}
|
||||
const isCached = inReqCache || inObjCache || inObjIdCache;
|
||||
const isCached = inReqCache || inObjCache;
|
||||
const isPending = this.isPending(request);
|
||||
return isCached || isPending;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../shared/ngrx/type';
|
||||
import { } from './index.reducer';
|
||||
import { IndexName } from './index.reducer';
|
||||
|
||||
/**
|
||||
* The list of HrefIndexAction type definitions
|
||||
@@ -19,7 +19,7 @@ export const IndexActionTypes = {
|
||||
export class AddToIndexAction implements Action {
|
||||
type = IndexActionTypes.ADD;
|
||||
payload: {
|
||||
name: string;
|
||||
name: IndexName;
|
||||
value: string;
|
||||
key: string;
|
||||
};
|
||||
@@ -34,7 +34,7 @@ export class AddToIndexAction implements Action {
|
||||
* @param value
|
||||
* the self link of the resource the key belongs to
|
||||
*/
|
||||
constructor(name: string, key: string, value: string) {
|
||||
constructor(name: IndexName, key: string, value: string) {
|
||||
this.payload = { name, key, value };
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ export class AddToIndexAction implements Action {
|
||||
export class RemoveFromIndexByValueAction implements Action {
|
||||
type = IndexActionTypes.REMOVE_BY_VALUE;
|
||||
payload: {
|
||||
name: string,
|
||||
name: IndexName,
|
||||
value: string
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ export class RemoveFromIndexByValueAction implements Action {
|
||||
* @param value
|
||||
* the value to remove the UUID for
|
||||
*/
|
||||
constructor(name: string, value: string) {
|
||||
constructor(name: IndexName, value: string) {
|
||||
this.payload = { name, value };
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export class RemoveFromIndexByValueAction implements Action {
|
||||
export class RemoveFromIndexBySubstringAction implements Action {
|
||||
type = IndexActionTypes.REMOVE_BY_SUBSTRING;
|
||||
payload: {
|
||||
name: string,
|
||||
name: IndexName,
|
||||
value: string
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ export class RemoveFromIndexBySubstringAction implements Action {
|
||||
* @param value
|
||||
* the value to remove the UUID for
|
||||
*/
|
||||
constructor(name: string, value: string) {
|
||||
constructor(name: IndexName, value: string) {
|
||||
this.payload = { name, value };
|
||||
}
|
||||
|
||||
|
@@ -10,55 +10,31 @@ import {
|
||||
import { RequestActionTypes, RequestConfigureAction } from '../data/request.actions';
|
||||
import { AddToIndexAction, RemoveFromIndexByValueAction } from './index.actions';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { getIdentiferByIndexName, IdentifierType, REQUEST } from './index.reducer';
|
||||
import { IndexName } from './index.reducer';
|
||||
import { RestRequestMethod } from '../data/rest-request-method';
|
||||
|
||||
@Injectable()
|
||||
export class IdentifierIndexEffects {
|
||||
export class UUIDIndexEffects {
|
||||
|
||||
@Effect() addObjectByUUID$ = this.actions$
|
||||
@Effect() addObject$ = this.actions$
|
||||
.pipe(
|
||||
ofType(ObjectCacheActionTypes.ADD),
|
||||
filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.uuid)),
|
||||
map((action: AddToObjectCacheAction) => {
|
||||
return new AddToIndexAction(
|
||||
getIdentiferByIndexName(IdentifierType.UUID),
|
||||
IndexName.OBJECT,
|
||||
action.payload.objectToCache.uuid,
|
||||
action.payload.objectToCache.self
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect() addObjectByHandle$ = this.actions$
|
||||
.pipe(
|
||||
ofType(ObjectCacheActionTypes.ADD),
|
||||
filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.handle)),
|
||||
map((action: AddToObjectCacheAction) => {
|
||||
return new AddToIndexAction(
|
||||
getIdentiferByIndexName(IdentifierType.HANDLE),
|
||||
action.payload.objectToCache.handle,
|
||||
action.payload.objectToCache.self
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect() removeObjectByUUID$ = this.actions$
|
||||
@Effect() removeObject$ = this.actions$
|
||||
.pipe(
|
||||
ofType(ObjectCacheActionTypes.REMOVE),
|
||||
map((action: RemoveFromObjectCacheAction) => {
|
||||
return new RemoveFromIndexByValueAction(
|
||||
getIdentiferByIndexName(IdentifierType.UUID),
|
||||
action.payload
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect() removeObjectByHandle$ = this.actions$
|
||||
.pipe(
|
||||
ofType(ObjectCacheActionTypes.REMOVE),
|
||||
map((action: RemoveFromObjectCacheAction) => {
|
||||
return new RemoveFromIndexByValueAction(
|
||||
getIdentiferByIndexName(IdentifierType.HANDLE),
|
||||
IndexName.OBJECT,
|
||||
action.payload
|
||||
);
|
||||
})
|
||||
@@ -70,7 +46,7 @@ export class IdentifierIndexEffects {
|
||||
filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.GET),
|
||||
map((action: RequestConfigureAction) => {
|
||||
return new AddToIndexAction(
|
||||
REQUEST,
|
||||
IndexName.REQUEST,
|
||||
action.payload.href,
|
||||
action.payload.uuid
|
||||
);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as deepFreeze from 'deep-freeze';
|
||||
|
||||
import { getIdentiferByIndexName, IdentifierType, indexReducer, MetaIndexState, REQUEST, } from './index.reducer';
|
||||
import { IndexName, indexReducer, MetaIndexState } from './index.reducer';
|
||||
import { AddToIndexAction, RemoveFromIndexBySubstringAction, RemoveFromIndexByValueAction } from './index.actions';
|
||||
|
||||
class NullAction extends AddToIndexAction {
|
||||
@@ -15,19 +15,14 @@ class NullAction extends AddToIndexAction {
|
||||
describe('requestReducer', () => {
|
||||
const key1 = '567a639f-f5ff-4126-807c-b7d0910808c8';
|
||||
const key2 = '1911e8a4-6939-490c-b58b-a5d70f8d91fb';
|
||||
const key3 = '123456789/22';
|
||||
const val1 = 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/567a639f-f5ff-4126-807c-b7d0910808c8';
|
||||
const val2 = 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/1911e8a4-6939-490c-b58b-a5d70f8d91fb';
|
||||
const uuidIndex = getIdentiferByIndexName(IdentifierType.UUID);
|
||||
const handleIndex = getIdentiferByIndexName(IdentifierType.HANDLE);
|
||||
const testState: MetaIndexState = {
|
||||
'object/uuid-to-self-link/uuid': {
|
||||
[IndexName.OBJECT]: {
|
||||
[key1]: val1
|
||||
},'object/uuid-to-self-link/handle': {
|
||||
[key3]: val1
|
||||
},'get-request/href-to-uuid': {
|
||||
},[IndexName.REQUEST]: {
|
||||
[key1]: val1
|
||||
},'get-request/configured-to-cache-uuid': {
|
||||
},[IndexName.UUID_MAPPING]: {
|
||||
[key1]: val1
|
||||
}
|
||||
};
|
||||
@@ -50,38 +45,27 @@ describe('requestReducer', () => {
|
||||
it('should add the \'key\' with the corresponding \'value\' to the correct substate, in response to an ADD action', () => {
|
||||
const state = testState;
|
||||
|
||||
const action = new AddToIndexAction(REQUEST, key2, val2);
|
||||
const action = new AddToIndexAction(IndexName.REQUEST, key2, val2);
|
||||
const newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[REQUEST][key2]).toEqual(val2);
|
||||
expect(newState[IndexName.REQUEST][key2]).toEqual(val2);
|
||||
});
|
||||
|
||||
it('should remove the given \'value\' from its corresponding \'key\' in the correct substate, in response to a REMOVE_BY_VALUE action', () => {
|
||||
const state = testState;
|
||||
|
||||
let action = new RemoveFromIndexByValueAction(uuidIndex, val1);
|
||||
let newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[uuidIndex][key1]).toBeUndefined();
|
||||
|
||||
action = new RemoveFromIndexByValueAction(handleIndex, val1);
|
||||
newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[handleIndex][key3]).toBeUndefined();
|
||||
const action = new RemoveFromIndexByValueAction(IndexName.OBJECT, val1);
|
||||
const newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[IndexName.OBJECT][key1]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should remove the given \'value\' from its corresponding \'key\' in the correct substate, in response to a REMOVE_BY_SUBSTRING action', () => {
|
||||
const state = testState;
|
||||
|
||||
let action = new RemoveFromIndexBySubstringAction(uuidIndex, key1);
|
||||
let newState = indexReducer(state, action);
|
||||
const action = new RemoveFromIndexBySubstringAction(IndexName.OBJECT, key1);
|
||||
const newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[uuidIndex][key1]).toBeUndefined();
|
||||
|
||||
action = new RemoveFromIndexBySubstringAction(handleIndex, key3);
|
||||
newState = indexReducer(state, action);
|
||||
|
||||
expect(newState[uuidIndex][key3]).toBeUndefined();
|
||||
expect(newState[IndexName.OBJECT][key1]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
@@ -6,25 +6,23 @@ import {
|
||||
RemoveFromIndexByValueAction
|
||||
} from './index.actions';
|
||||
|
||||
export enum IdentifierType {
|
||||
UUID ='uuid',
|
||||
HANDLE = 'handle'
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum containing all index names
|
||||
*/
|
||||
export enum IndexName {
|
||||
// Contains all objects in the object cache indexed by UUID
|
||||
OBJECT = 'object/uuid-to-self-link',
|
||||
|
||||
// contains all requests in the request cache indexed by UUID
|
||||
REQUEST = 'get-request/href-to-uuid',
|
||||
|
||||
/**
|
||||
* Contains the UUIDs of requests that were sent to the server and
|
||||
* have their responses cached, indexed by the UUIDs of requests that
|
||||
* weren't sent because the response they requested was already cached
|
||||
*/
|
||||
export const UUID_MAPPING = 'get-request/configured-to-cache-uuid';
|
||||
|
||||
// contains all requests in the request cache indexed by UUID
|
||||
export const REQUEST = 'get-request/href-to-uuid';
|
||||
|
||||
// returns the index for the provided id type (uuid, handle)
|
||||
export const getIdentiferByIndexName = (idType: IdentifierType): string => {
|
||||
return `object/uuid-to-self-link/${idType}`;
|
||||
};
|
||||
UUID_MAPPING = 'get-request/configured-to-cache-uuid'
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of a single index
|
||||
@@ -36,11 +34,8 @@ export interface IndexState {
|
||||
/**
|
||||
* The state that contains all indices
|
||||
*/
|
||||
export interface MetaIndexState {
|
||||
'get-request/configured-to-cache-uuid': IndexState,
|
||||
'get-request/href-to-uuid': IndexState,
|
||||
'object/uuid-to-self-link/uuid': IndexState,
|
||||
'object/uuid-to-self-link/handle': IndexState
|
||||
export type MetaIndexState = {
|
||||
[name in IndexName]: IndexState
|
||||
}
|
||||
|
||||
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
|
||||
|
@@ -3,14 +3,7 @@ import { AppState } from '../../app.reducer';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { coreSelector } from '../core.selectors';
|
||||
import {
|
||||
getIdentiferByIndexName,
|
||||
IdentifierType,
|
||||
IndexState,
|
||||
MetaIndexState,
|
||||
REQUEST,
|
||||
UUID_MAPPING
|
||||
} from './index.reducer';
|
||||
import { IndexName, IndexState, MetaIndexState } from './index.reducer';
|
||||
|
||||
/**
|
||||
* Return the MetaIndexState based on the CoreSate
|
||||
@@ -27,17 +20,13 @@ export const metaIndexSelector: MemoizedSelector<AppState, MetaIndexState> = cre
|
||||
* Return the object index based on the MetaIndexState
|
||||
* It contains all objects in the object cache indexed by UUID
|
||||
*
|
||||
* @param identifierType the type of index, used to select index from state
|
||||
*
|
||||
* @returns
|
||||
* a MemoizedSelector to select the object index
|
||||
*/
|
||||
export const objectIndexSelector = (identifierType: IdentifierType = IdentifierType.UUID): MemoizedSelector<AppState, IndexState> => {
|
||||
return createSelector(
|
||||
export const objectIndexSelector: MemoizedSelector<AppState, IndexState> = createSelector(
|
||||
metaIndexSelector,
|
||||
(state: MetaIndexState) => state[getIdentiferByIndexName(identifierType)]
|
||||
);
|
||||
}
|
||||
(state: MetaIndexState) => state[IndexName.OBJECT]
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the request index based on the MetaIndexState
|
||||
@@ -47,7 +36,7 @@ export const objectIndexSelector = (identifierType: IdentifierType = IdentifierT
|
||||
*/
|
||||
export const requestIndexSelector: MemoizedSelector<AppState, IndexState> = createSelector(
|
||||
metaIndexSelector,
|
||||
(state: MetaIndexState) => state[REQUEST]
|
||||
(state: MetaIndexState) => state[IndexName.REQUEST]
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -58,7 +47,7 @@ export const requestIndexSelector: MemoizedSelector<AppState, IndexState> = crea
|
||||
*/
|
||||
export const requestUUIDIndexSelector: MemoizedSelector<AppState, IndexState> = createSelector(
|
||||
metaIndexSelector,
|
||||
(state: MetaIndexState) => state[UUID_MAPPING]
|
||||
(state: MetaIndexState) => state[IndexName.UUID_MAPPING]
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -71,9 +60,9 @@ export const requestUUIDIndexSelector: MemoizedSelector<AppState, IndexState> =
|
||||
* a MemoizedSelector to select the self link
|
||||
*/
|
||||
export const selfLinkFromUuidSelector =
|
||||
(id: string, identifierType: IdentifierType = IdentifierType.UUID): MemoizedSelector<AppState, string> => createSelector(
|
||||
objectIndexSelector(identifierType),
|
||||
(state: IndexState) => hasValue(state) ? state[id] : undefined
|
||||
(uuid: string): MemoizedSelector<AppState, string> => createSelector(
|
||||
objectIndexSelector,
|
||||
(state: IndexState) => hasValue(state) ? state[uuid] : undefined
|
||||
);
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user