1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 14:23:32 +00:00

Ps/introduce single user state (#7053)

* Specify state provider for currently active user

* Split active and single user States

UserStateProvider is still the mechanism to build each State object.
The SingleUserState is basically a repeat of GlobalState, but with
additional scoping.

* Fixup global state cache

* fix fakers to new interface

* Make userId available in single user state

* Split providers by dependency requirements

This allows usage of the single state provider in contexts that would
otherwise form circular dependencies.

* Offer convenience wrapper classes for common use

* Import for docs

* Bind wrapped methods
This commit is contained in:
Matt Gibson
2023-12-05 10:20:16 -05:00
committed by GitHub
parent 3deb6ea0c8
commit e045c6b103
17 changed files with 629 additions and 104 deletions

View File

@@ -0,0 +1,58 @@
import { UserId } from "../../../types/guid";
import { EncryptService } from "../../abstractions/encrypt.service";
import {
AbstractMemoryStorageService,
AbstractStorageService,
ObservableStorageService,
} from "../../abstractions/storage.service";
import { KeyDefinition } from "../key-definition";
import { StorageLocation } from "../state-definition";
import { SingleUserState } from "../user-state";
import { SingleUserStateProvider } from "../user-state.provider";
import { DefaultSingleUserState } from "./default-single-user-state";
export class DefaultSingleUserStateProvider implements SingleUserStateProvider {
private cache: Record<string, SingleUserState<unknown>> = {};
constructor(
protected encryptService: EncryptService,
protected memoryStorage: AbstractMemoryStorageService & ObservableStorageService,
protected diskStorage: AbstractStorageService & ObservableStorageService,
) {}
get<T>(userId: UserId, keyDefinition: KeyDefinition<T>): SingleUserState<T> {
const cacheKey = keyDefinition.buildCacheKey("user", userId);
const existingUserState = this.cache[cacheKey];
if (existingUserState != null) {
// I have to cast out of the unknown generic but this should be safe if rules
// around domain token are made
return existingUserState as SingleUserState<T>;
}
const newUserState = this.buildSingleUserState(userId, keyDefinition);
this.cache[cacheKey] = newUserState;
return newUserState;
}
protected buildSingleUserState<T>(
userId: UserId,
keyDefinition: KeyDefinition<T>,
): SingleUserState<T> {
return new DefaultSingleUserState<T>(
userId,
keyDefinition,
this.encryptService,
this.getLocation(keyDefinition.stateDefinition.storageLocation),
);
}
private getLocation(location: StorageLocation) {
switch (location) {
case "disk":
return this.diskStorage;
case "memory":
return this.memoryStorage;
}
}
}