import { Resource } from '@ngxp/rest'; import { Observable, map, withLatestFrom } from 'rxjs'; import { StateResource } from '../resource/resource.util'; import { ApiSingleResourceStateService } from './state.service'; export class ApiStateServiceExecuter<B extends Resource, T extends Resource> { private stateService: ApiSingleResourceStateService<B, T>; private baseResource: Observable<StateResource<T>>; shouldExecute: boolean; public static init<B extends Resource, T extends Resource>( stateService: ApiSingleResourceStateService<B, T>, ): ApiStateServiceExecuter<B, T> { return new ApiStateServiceExecuter<B, T>(stateService); } constructor(stateService: ApiSingleResourceStateService<B, T>) { this.stateService = stateService; this.shouldExecute = true; } public withBaseResource(baseResource: Observable<StateResource<T>>): this { this.baseResource = baseResource; return this; } public execute(runnable: (resource: T) => void): Observable<StateResource<T>> { return this.baseResource.pipe( withLatestFrom(this.stateService.selectResource()), map(([baseStateResource, stateResource]) => { if (this.shouldExecute && !baseStateResource.loading) { runnable(stateResource.resource); this.shouldExecute = false; return { ...baseStateResource, loading: true }; } return baseStateResource; }), ); } }