Link derived state fake to parent observable. (#7922)

This commit is contained in:
Matt Gibson 2024-02-13 15:26:56 -05:00 committed by GitHub
parent aa11feec1b
commit f0ae318f57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 5 deletions

View File

@ -198,7 +198,7 @@ export class FakeDerivedStateProvider implements DerivedStateProvider {
let result = this.states.get(deriveDefinition.buildCacheKey()) as DerivedState<TTo>;
if (result == null) {
result = new FakeDerivedState<TTo>();
result = new FakeDerivedState(parentState$, deriveDefinition, dependencies);
this.states.set(deriveDefinition.buildCacheKey(), result);
}
return result;

View File

@ -1,4 +1,4 @@
import { Observable, ReplaySubject, firstValueFrom, map, timeout } from "rxjs";
import { Observable, ReplaySubject, concatMap, firstValueFrom, map, timeout } from "rxjs";
import {
DerivedState,
@ -6,12 +6,14 @@ import {
SingleUserState,
ActiveUserState,
KeyDefinition,
DeriveDefinition,
} from "../src/platform/state";
// eslint-disable-next-line import/no-restricted-paths -- using unexposed options for clean typing in test class
import { StateUpdateOptions } from "../src/platform/state/state-update-options";
// eslint-disable-next-line import/no-restricted-paths -- using unexposed options for clean typing in test class
import { CombinedState, activeMarker } from "../src/platform/state/user-state";
import { UserId } from "../src/types/guid";
import { DerivedStateDependencies } from "../src/types/state";
import { FakeAccountService } from "./fake-account-service";
@ -204,11 +206,33 @@ export class FakeActiveUserState<T> implements ActiveUserState<T> {
}
}
export class FakeDerivedState<T> implements DerivedState<T> {
export class FakeDerivedState<TFrom, TTo, TDeps extends DerivedStateDependencies>
implements DerivedState<TTo>
{
// eslint-disable-next-line rxjs/no-exposed-subjects -- exposed for testing setup
stateSubject = new ReplaySubject<T>(1);
stateSubject = new ReplaySubject<TTo>(1);
forceValue(value: T): Promise<T> {
constructor(
parentState$: Observable<TFrom>,
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
dependencies: TDeps,
) {
parentState$
.pipe(
concatMap(async (v) => {
const newState = deriveDefinition.derive(v, dependencies);
if (newState instanceof Promise) {
return newState;
}
return Promise.resolve(newState);
}),
)
.subscribe((newState) => {
this.stateSubject.next(newState);
});
}
forceValue(value: TTo): Promise<TTo> {
this.stateSubject.next(value);
return Promise.resolve(value);
}