import { Observable, map, firstValueFrom, of, switchMap, take } from "rxjs"; import { KeyDefinition, PROVIDERS_DISK, StateProvider } from "../../platform/state"; import { UserId } from "../../types/guid"; import { ProviderService as ProviderServiceAbstraction } from "../abstractions/provider.service"; import { ProviderData } from "../models/data/provider.data"; import { Provider } from "../models/domain/provider"; export const PROVIDERS = KeyDefinition.record(PROVIDERS_DISK, "providers", { deserializer: (obj: ProviderData) => obj, }); function mapToSingleProvider(providerId: string) { return map((providers) => providers?.find((p) => p.id === providerId)); } export class ProviderService implements ProviderServiceAbstraction { constructor(private stateProvider: StateProvider) {} private providers$(userId?: UserId): Observable { // FIXME: Can be replaced with `getUserStateOrDefault$` if we weren't trying to pick this. return ( userId != null ? this.stateProvider.getUser(userId, PROVIDERS).state$ : this.stateProvider.activeUserId$.pipe( take(1), switchMap((userId) => userId != null ? this.stateProvider.getUser(userId, PROVIDERS).state$ : of(null), ), ) ).pipe(this.mapProviderRecordToArray()); } private mapProviderRecordToArray() { return map, Provider[]>((providers) => Object.values(providers ?? {})?.map((o) => new Provider(o)), ); } async get(id: string): Promise { return await firstValueFrom(this.providers$().pipe(mapToSingleProvider(id))); } async getAll(): Promise { return await firstValueFrom(this.providers$()); } async save(providers: { [id: string]: ProviderData }, userId?: UserId) { await this.stateProvider.setUserState(PROVIDERS, providers, userId); } }