mirror of
https://github.com/bitwarden/browser
synced 2026-02-13 15:03:26 +00:00
* Introduce browser large object storage location. This location is encrypted and serialized to disk in order to allow for storage of uncountable things like vault items that take a significant amount of time to prepare, but are not guaranteed to fit within session storage. however, limit the need to write to disk is a big benefit, so _most_ things are written to storage.session instead, where things specifically flagged as large will be moved to disk-backed memory * Store derived values in large object store for browser * Fix AbstractMemoryStorageService implementation
59 lines
2.2 KiB
TypeScript
59 lines
2.2 KiB
TypeScript
import { Observable } from "rxjs";
|
|
|
|
import { DerivedStateDependencies } from "../../../types/state";
|
|
import {
|
|
AbstractStorageService,
|
|
ObservableStorageService,
|
|
} from "../../abstractions/storage.service";
|
|
import { StorageServiceProvider } from "../../services/storage-service.provider";
|
|
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 storageServiceProvider: StorageServiceProvider) {}
|
|
|
|
get<TFrom, TTo, TDeps extends DerivedStateDependencies>(
|
|
parentState$: Observable<TFrom>,
|
|
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
|
|
dependencies: TDeps,
|
|
): DerivedState<TTo> {
|
|
// TODO: we probably want to support optional normal memory storage for browser
|
|
const [location, storageService] = this.storageServiceProvider.get("memory", {
|
|
browser: "memory-large-object",
|
|
});
|
|
const cacheKey = deriveDefinition.buildCacheKey(location);
|
|
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, [
|
|
location,
|
|
storageService,
|
|
]);
|
|
this.cache[cacheKey] = newDerivedState;
|
|
return newDerivedState;
|
|
}
|
|
|
|
protected buildDerivedState<TFrom, TTo, TDeps extends DerivedStateDependencies>(
|
|
parentState$: Observable<TFrom>,
|
|
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
|
|
dependencies: TDeps,
|
|
storageLocation: [string, AbstractStorageService & ObservableStorageService],
|
|
): DerivedState<TTo> {
|
|
return new DefaultDerivedState<TFrom, TTo, TDeps>(
|
|
parentState$,
|
|
deriveDefinition,
|
|
storageLocation[1],
|
|
dependencies,
|
|
);
|
|
}
|
|
}
|