import { filter, map, switchMap, take } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { AddToObjectCacheAction, ObjectCacheActionTypes, RemoveFromObjectCacheAction } from '../cache/object-cache.actions'; import { RequestActionTypes, RequestConfigureAction, RequestStaleAction } from '../data/request.actions'; import { AddToIndexAction, RemoveFromIndexByValueAction } from './index.actions'; import { hasValue } from '../../shared/empty.util'; import { RestRequestMethod } from '../data/rest-request-method'; import { getUrlWithoutEmbedParams, uuidFromHrefSelector } from './index.selectors'; import { Store, select } from '@ngrx/store'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; import { IndexName } from './index-name.model'; import { CoreState } from '../core-state.model'; @Injectable() export class UUIDIndexEffects { addObject$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.ADD), filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache) && hasValue(action.payload.objectToCache.uuid)), map((action: AddToObjectCacheAction) => { return new AddToIndexAction( IndexName.OBJECT, action.payload.objectToCache.uuid, action.payload.objectToCache._links.self.href ); }) )); /** * Adds an alternative link to an object to the ALTERNATIVE_OBJECT_LINK index * When the self link of the objectToCache is not the same as the alternativeLink */ addAlternativeObjectLink$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.ADD), map((action: AddToObjectCacheAction) => { const alternativeLink = action.payload.alternativeLink; const selfLink = hasValue(action.payload.objectToCache?._links?.self) ? action.payload.objectToCache._links.self.href : alternativeLink; if (hasValue(alternativeLink) && alternativeLink !== selfLink) { return new AddToIndexAction( IndexName.ALTERNATIVE_OBJECT_LINK, alternativeLink, selfLink ); } else { return new NoOpAction(); } }) )); removeObject$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.REMOVE), map((action: RemoveFromObjectCacheAction) => { return new RemoveFromIndexByValueAction( IndexName.OBJECT, action.payload ); }) )); addRequest$ = createEffect(() => this.actions$ .pipe( ofType(RequestActionTypes.CONFIGURE), filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.GET), switchMap((action: RequestConfigureAction) => { const href = getUrlWithoutEmbedParams(action.payload.href); return this.store.pipe( select(uuidFromHrefSelector(href)), take(1), map((uuid: string) => [action, uuid]) ); } ), switchMap(([action, uuid]: [RequestConfigureAction, string]) => { let actions = []; if (hasValue(uuid)) { actions = [new RequestStaleAction(uuid)]; } actions = [...actions, new AddToIndexAction( IndexName.REQUEST, getUrlWithoutEmbedParams(action.payload.href), action.payload.uuid )]; return actions; }) )); constructor(private actions$: Actions, private store: Store) { } }