mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
Rework derived state (#7290)
* Remove derived state from state classes * Create provider for derived state Derived state is automatically stored to memory storage, but can be derived from any observable. * Fixup state provider method definitions * Test `DefaultDerivedState` * remove implementation notes * Write docs for derived state * fixup derived state provider types * Implement buffered delayUntil operator * Move state types to a common module * Move mock ports to centra location * Alias DerivedStateDependency type * Add dependencies to browser * Prefer internal rxjs operators for ref counting * WIP * Ensure complete on subjects * Foreground/background messaging for browser Defers work for browser to the background * Test foreground port behaviors * Inject foreground and background derived state services * remove unnecessary class field * Adhere to required options * Add dderived state to CLI * Prefer type definition in type parameters to options * Prefer instance method * Implements factory methods for common uses * Remove nothing test * Remove share subject reference Share manages connector subjects internally and will reuse them until refcount is 0 and the cleanup time has passed. Saving our own reference just risks memory leaks without real testability benefits. * Fix interaction state
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
import { ReplaySubject, firstValueFrom, timeout } from "rxjs";
|
||||
|
||||
import {
|
||||
DerivedUserState,
|
||||
GlobalState,
|
||||
SingleUserState,
|
||||
ActiveUserState,
|
||||
} from "../src/platform/state";
|
||||
import { DerivedState, GlobalState, SingleUserState, ActiveUserState } 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
|
||||
@@ -92,10 +87,6 @@ export class FakeUserState<T> implements UserState<T> {
|
||||
options?: StateUpdateOptions<T, TCombine>,
|
||||
) => Promise<T> = jest.fn();
|
||||
|
||||
createDerived: <TTo>(
|
||||
converter: (data: T, context: any) => Promise<TTo>,
|
||||
) => DerivedUserState<TTo> = jest.fn();
|
||||
|
||||
getFromState: () => Promise<T> = jest.fn(async () => {
|
||||
return await firstValueFrom(this.state$.pipe(timeout(10)));
|
||||
});
|
||||
@@ -113,3 +104,18 @@ export class FakeSingleUserState<T> extends FakeUserState<T> implements SingleUs
|
||||
export class FakeActiveUserState<T> extends FakeUserState<T> implements ActiveUserState<T> {
|
||||
[activeMarker]: true;
|
||||
}
|
||||
|
||||
export class FakeDerivedState<T> implements DerivedState<T> {
|
||||
// eslint-disable-next-line rxjs/no-exposed-subjects -- exposed for testing setup
|
||||
stateSubject = new ReplaySubject<T>(1);
|
||||
|
||||
forceValue(value: T): Promise<T> {
|
||||
this.stateSubject.next(value);
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
forceValueMock = this.forceValue as jest.MockedFunction<typeof this.forceValue>;
|
||||
|
||||
get state$() {
|
||||
return this.stateSubject.asObservable();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user