mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
Resolve state <-> state-test-utils circular dependency (#16093)
* Resolve state <-> state-test-utils circular dependency * Fix type errors
This commit is contained in:
48
libs/state-internal/src/default-derived-state.ts
Normal file
48
libs/state-internal/src/default-derived-state.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Observable, ReplaySubject, Subject, concatMap, merge, share, timer } from "rxjs";
|
||||
|
||||
import { DeriveDefinition, DerivedState, DerivedStateDependencies } from "@bitwarden/state";
|
||||
|
||||
/**
|
||||
* Default derived state
|
||||
*/
|
||||
export class DefaultDerivedState<TFrom, TTo, TDeps extends DerivedStateDependencies>
|
||||
implements DerivedState<TTo>
|
||||
{
|
||||
private readonly storageKey: string;
|
||||
private forcedValueSubject = new Subject<TTo>();
|
||||
|
||||
state$: Observable<TTo>;
|
||||
|
||||
constructor(
|
||||
private parentState$: Observable<TFrom>,
|
||||
protected deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
|
||||
private dependencies: TDeps,
|
||||
) {
|
||||
this.storageKey = deriveDefinition.storageKey;
|
||||
|
||||
const derivedState$ = this.parentState$.pipe(
|
||||
concatMap(async (state) => {
|
||||
let derivedStateOrPromise = this.deriveDefinition.derive(state, this.dependencies);
|
||||
if (derivedStateOrPromise instanceof Promise) {
|
||||
derivedStateOrPromise = await derivedStateOrPromise;
|
||||
}
|
||||
const derivedState = derivedStateOrPromise;
|
||||
return derivedState;
|
||||
}),
|
||||
);
|
||||
|
||||
this.state$ = merge(this.forcedValueSubject, derivedState$).pipe(
|
||||
share({
|
||||
connector: () => {
|
||||
return new ReplaySubject<TTo>(1);
|
||||
},
|
||||
resetOnRefCountZero: () => timer(this.deriveDefinition.cleanupDelayMs),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async forceValue(value: TTo) {
|
||||
this.forcedValueSubject.next(value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user