diff --git a/libs/common/src/models/domain/state.spec.ts b/libs/common/src/models/domain/state.spec.ts index 64e71d7cb2c..aa4f36549c2 100644 --- a/libs/common/src/models/domain/state.spec.ts +++ b/libs/common/src/models/domain/state.spec.ts @@ -4,22 +4,25 @@ import { State } from "./state"; describe("state", () => { describe("fromJSON", () => { it("should deserialize to an instance of itself", () => { - expect(State.fromJSON({})).toBeInstanceOf(State); + expect(State.fromJSON({}, () => new Account({}))).toBeInstanceOf(State); }); it("should always assign an object to accounts", () => { - const state = State.fromJSON({}); + const state = State.fromJSON({}, () => new Account({})); expect(state.accounts).not.toBeNull(); expect(state.accounts).toEqual({}); }); it("should build an account map", () => { const accountsSpy = jest.spyOn(Account, "fromJSON"); - const state = State.fromJSON({ - accounts: { - userId: {}, + const state = State.fromJSON( + { + accounts: { + userId: {}, + }, }, - }); + Account.fromJSON + ); expect(state.accounts["userId"]).toBeInstanceOf(Account); expect(accountsSpy).toHaveBeenCalled(); diff --git a/libs/common/src/models/domain/state.ts b/libs/common/src/models/domain/state.ts index be99d9bdabe..c08e6fe70f6 100644 --- a/libs/common/src/models/domain/state.ts +++ b/libs/common/src/models/domain/state.ts @@ -19,26 +19,28 @@ export class State< // TODO, make Jsonify work. It currently doesn't because Globals doesn't implement Jsonify. static fromJSON( - obj: any + obj: any, + accountDeserializer: (json: Jsonify) => TAccount ): State { if (obj == null) { return null; } return Object.assign(new State(null), obj, { - accounts: State.buildAccountMapFromJSON(obj?.accounts), + accounts: State.buildAccountMapFromJSON(obj?.accounts, accountDeserializer), }); } - private static buildAccountMapFromJSON( - jsonAccounts: Jsonify<{ [userId: string]: Jsonify }> + private static buildAccountMapFromJSON( + jsonAccounts: { [userId: string]: Jsonify }, + accountDeserializer: (json: Jsonify) => TAccount ) { if (!jsonAccounts) { return {}; } - const accounts: { [userId: string]: Account } = {}; + const accounts: { [userId: string]: TAccount } = {}; for (const userId in jsonAccounts) { - accounts[userId] = Account.fromJSON(jsonAccounts[userId]); + accounts[userId] = accountDeserializer(jsonAccounts[userId]); } return accounts; } diff --git a/libs/common/src/services/state.service.ts b/libs/common/src/services/state.service.ts index 8391cc6e3e0..335a010c088 100644 --- a/libs/common/src/services/state.service.ts +++ b/libs/common/src/services/state.service.ts @@ -1,4 +1,5 @@ import { BehaviorSubject, concatMap } from "rxjs"; +import { Jsonify } from "type-fest"; import { LogService } from "../abstractions/log.service"; import { StateService as StateServiceAbstraction } from "../abstractions/state.service"; @@ -80,6 +81,9 @@ export class StateService< private accountDiskCache = new Map(); + // default account serializer, must be overridden by child class + protected accountDeserializer = Account.fromJSON as (json: Jsonify) => TAccount; + constructor( protected storageService: AbstractStorageService, protected secureStorageService: AbstractStorageService, @@ -2745,7 +2749,7 @@ export class StateService< protected async state(): Promise> { const state = await this.memoryStorageService.get>(keys.state, { - deserializer: (s) => State.fromJSON(s), + deserializer: (s) => State.fromJSON(s, this.accountDeserializer), }); return state; }