mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 06:43:35 +00:00
Ps/pm 2910/state framework improvements (#6860)
* Allow for update logic in state update callbacks * Prefer reading updates to sending in stream * Inform state providers when they must deserialize * Update DefaultGlobalState to act more like DefaultUserState * Fully Implement AbstractStorageService * Add KeyDefinitionOptions * Address PR feedback * More Descriptive Error --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { awaitAsync } from "@bitwarden/angular/../test-utils";
|
||||
import { awaitAsync } from "@bitwarden/common/../spec/utils";
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject, ReplaySubject } from "rxjs";
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ import { fromChromeEvent } from "../../browser/from-chrome-event";
|
||||
export default abstract class AbstractChromeStorageService implements AbstractStorageService {
|
||||
constructor(protected chromeStorageApi: chrome.storage.StorageArea) {}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$(): Observable<StorageUpdate> {
|
||||
return fromChromeEvent(this.chromeStorageApi.onChanged).pipe(
|
||||
mergeMap(([changes]) => {
|
||||
@@ -27,7 +30,6 @@ export default abstract class AbstractChromeStorageService implements AbstractSt
|
||||
key: key,
|
||||
// For removes this property will not exist but then it will just be
|
||||
// undefined which is fine.
|
||||
value: change.newValue,
|
||||
updateType: updateType,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -35,6 +35,10 @@ export class LocalBackedSessionStorageService extends AbstractMemoryStorageServi
|
||||
super();
|
||||
}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
get updates$() {
|
||||
return this.updatesSubject.asObservable();
|
||||
}
|
||||
|
||||
@@ -107,6 +107,9 @@ export class LowdbStorageService implements AbstractStorageService {
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$() {
|
||||
return this.updatesSubject.asObservable();
|
||||
}
|
||||
@@ -133,7 +136,7 @@ export class LowdbStorageService implements AbstractStorageService {
|
||||
return this.lockDbFile(() => {
|
||||
this.readForNoCache();
|
||||
this.db.set(key, obj).write();
|
||||
this.updatesSubject.next({ key, value: obj, updateType: "save" });
|
||||
this.updatesSubject.next({ key, updateType: "save" });
|
||||
this.logService.debug(`Successfully wrote ${key} to db`);
|
||||
return;
|
||||
});
|
||||
@@ -144,7 +147,7 @@ export class LowdbStorageService implements AbstractStorageService {
|
||||
return this.lockDbFile(() => {
|
||||
this.readForNoCache();
|
||||
this.db.unset(key).write();
|
||||
this.updatesSubject.next({ key, value: null, updateType: "remove" });
|
||||
this.updatesSubject.next({ key, updateType: "remove" });
|
||||
this.logService.debug(`Successfully removed ${key} from db`);
|
||||
return;
|
||||
});
|
||||
|
||||
@@ -14,6 +14,10 @@ export class NodeEnvSecureStorageService implements AbstractStorageService {
|
||||
private cryptoService: () => CryptoService
|
||||
) {}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
get updates$() {
|
||||
return throwError(
|
||||
() => new Error("Secure storage implementations cannot have their updates subscribed to.")
|
||||
|
||||
@@ -4,6 +4,9 @@ import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/
|
||||
import { StorageOptions } from "@bitwarden/common/platform/models/domain/storage-options";
|
||||
|
||||
export class ElectronRendererSecureStorageService implements AbstractStorageService {
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$() {
|
||||
return throwError(
|
||||
() => new Error("Secure storage implementations cannot have their updates subscribed to.")
|
||||
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
export class ElectronRendererStorageService implements AbstractStorageService {
|
||||
private updatesSubject = new Subject<StorageUpdate>();
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$() {
|
||||
return this.updatesSubject.asObservable();
|
||||
}
|
||||
@@ -22,11 +25,11 @@ export class ElectronRendererStorageService implements AbstractStorageService {
|
||||
|
||||
async save<T>(key: string, obj: T): Promise<void> {
|
||||
await ipc.platform.storage.save(key, obj);
|
||||
this.updatesSubject.next({ key, value: obj, updateType: "save" });
|
||||
this.updatesSubject.next({ key, updateType: "save" });
|
||||
}
|
||||
|
||||
async remove(key: string): Promise<void> {
|
||||
await ipc.platform.storage.remove(key);
|
||||
this.updatesSubject.next({ key, value: null, updateType: "remove" });
|
||||
this.updatesSubject.next({ key, updateType: "remove" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ export class ElectronStorageService implements AbstractStorageService {
|
||||
});
|
||||
}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$() {
|
||||
return this.updatesSubject.asObservable();
|
||||
}
|
||||
@@ -84,13 +87,13 @@ export class ElectronStorageService implements AbstractStorageService {
|
||||
obj = Array.from(obj);
|
||||
}
|
||||
this.store.set(key, obj);
|
||||
this.updatesSubject.next({ key, value: obj, updateType: "save" });
|
||||
this.updatesSubject.next({ key, updateType: "save" });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
remove(key: string): Promise<void> {
|
||||
this.store.delete(key);
|
||||
this.updatesSubject.next({ key, value: null, updateType: "remove" });
|
||||
this.updatesSubject.next({ key, updateType: "remove" });
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ export class HtmlStorageService implements AbstractStorageService {
|
||||
return { htmlStorageLocation: HtmlStorageLocation.Session };
|
||||
}
|
||||
|
||||
get valuesRequireDeserialization(): boolean {
|
||||
return true;
|
||||
}
|
||||
get updates$() {
|
||||
return this.updatesSubject.asObservable();
|
||||
}
|
||||
@@ -62,7 +65,7 @@ export class HtmlStorageService implements AbstractStorageService {
|
||||
window.sessionStorage.setItem(key, json);
|
||||
break;
|
||||
}
|
||||
this.updatesSubject.next({ key, value: obj, updateType: "save" });
|
||||
this.updatesSubject.next({ key, updateType: "save" });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -76,7 +79,7 @@ export class HtmlStorageService implements AbstractStorageService {
|
||||
window.sessionStorage.removeItem(key);
|
||||
break;
|
||||
}
|
||||
this.updatesSubject.next({ key, value: null, updateType: "remove" });
|
||||
this.updatesSubject.next({ key, updateType: "remove" });
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user