mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +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:
@@ -0,0 +1,49 @@
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { DerivedStateDependencies, ShapeToInstances } from "../../../types/state";
|
||||
import {
|
||||
AbstractStorageService,
|
||||
ObservableStorageService,
|
||||
} from "../../abstractions/storage.service";
|
||||
import { DeriveDefinition } from "../derive-definition";
|
||||
import { DerivedState } from "../derived-state";
|
||||
import { DerivedStateProvider } from "../derived-state.provider";
|
||||
|
||||
import { DefaultDerivedState } from "./default-derived-state";
|
||||
|
||||
export class DefaultDerivedStateProvider implements DerivedStateProvider {
|
||||
private cache: Record<string, DerivedState<unknown>> = {};
|
||||
|
||||
constructor(protected memoryStorage: AbstractStorageService & ObservableStorageService) {}
|
||||
|
||||
get<TFrom, TTo, TDeps extends DerivedStateDependencies>(
|
||||
parentState$: Observable<TFrom>,
|
||||
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
|
||||
dependencies: ShapeToInstances<TDeps>,
|
||||
): DerivedState<TTo> {
|
||||
const cacheKey = deriveDefinition.buildCacheKey();
|
||||
const existingDerivedState = this.cache[cacheKey];
|
||||
if (existingDerivedState != null) {
|
||||
// I have to cast out of the unknown generic but this should be safe if rules
|
||||
// around domain token are made
|
||||
return existingDerivedState as DefaultDerivedState<TFrom, TTo, TDeps>;
|
||||
}
|
||||
|
||||
const newDerivedState = this.buildDerivedState(parentState$, deriveDefinition, dependencies);
|
||||
this.cache[cacheKey] = newDerivedState;
|
||||
return newDerivedState;
|
||||
}
|
||||
|
||||
protected buildDerivedState<TFrom, TTo, TDeps extends DerivedStateDependencies>(
|
||||
parentState$: Observable<TFrom>,
|
||||
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
|
||||
dependencies: ShapeToInstances<TDeps>,
|
||||
): DerivedState<TTo> {
|
||||
return new DefaultDerivedState<TFrom, TTo, TDeps>(
|
||||
parentState$,
|
||||
deriveDefinition,
|
||||
this.memoryStorage,
|
||||
dependencies,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user