diff --git a/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts b/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts index b1216c0bafa..3f51828a59f 100644 --- a/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts +++ b/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts @@ -100,6 +100,24 @@ describe("DefaultSingleUserState", () => { ); expect(state).toBeTruthy(); }); + + it("should go to disk each subscription if a cleanupDelayMs of 0 is given", async () => { + const state = new DefaultSingleUserState( + userId, + new UserKeyDefinition(testStateDefinition, "test", { + cleanupDelayMs: 0, + deserializer: TestState.fromJSON, + clearOn: [], + }), + diskStorageService, + stateEventRegistrarService, + ); + + await firstValueFrom(state.state$); + await firstValueFrom(state.state$); + + expect(diskStorageService.mock.get).toHaveBeenCalledTimes(2); + }); }); describe("combinedState$", () => { diff --git a/libs/common/src/platform/state/implementations/state-base.ts b/libs/common/src/platform/state/implementations/state-base.ts index c09771033cc..9beab1200a1 100644 --- a/libs/common/src/platform/state/implementations/state-base.ts +++ b/libs/common/src/platform/state/implementations/state-base.ts @@ -48,15 +48,22 @@ export abstract class StateBase> }), ); - this.state$ = merge( + let state$ = merge( defer(() => getStoredValue(key, storageService, keyDefinition.deserializer)), storageUpdate$, - ).pipe( - share({ - connector: () => new ReplaySubject(1), - resetOnRefCountZero: () => timer(keyDefinition.cleanupDelayMs), - }), ); + + // If 0 cleanup is chosen, treat this as absolutely no cache + if (keyDefinition.cleanupDelayMs !== 0) { + state$ = state$.pipe( + share({ + connector: () => new ReplaySubject(1), + resetOnRefCountZero: () => timer(keyDefinition.cleanupDelayMs), + }), + ); + } + + this.state$ = state$; } async update( diff --git a/libs/common/src/platform/state/key-definition.spec.ts b/libs/common/src/platform/state/key-definition.spec.ts index ee926bccd8e..f68fb6f5ab6 100644 --- a/libs/common/src/platform/state/key-definition.spec.ts +++ b/libs/common/src/platform/state/key-definition.spec.ts @@ -38,12 +38,12 @@ describe("KeyDefinition", () => { expect(keyDefinition.cleanupDelayMs).toBe(500); }); - it.each([0, -1])("throws on 0 or negative (%s)", (testValue: number) => { + it("throws on negative", () => { expect( () => new KeyDefinition(fakeStateDefinition, "fake", { deserializer: (value) => value, - cleanupDelayMs: testValue, + cleanupDelayMs: -1, }), ).toThrow(); }); diff --git a/libs/common/src/platform/state/key-definition.ts b/libs/common/src/platform/state/key-definition.ts index bdabd8df50b..ea6ed4b2f30 100644 --- a/libs/common/src/platform/state/key-definition.ts +++ b/libs/common/src/platform/state/key-definition.ts @@ -50,9 +50,9 @@ export class KeyDefinition { throw new Error(`'deserializer' is a required property on key ${this.errorKeyName}`); } - if (options.cleanupDelayMs <= 0) { + if (options.cleanupDelayMs < 0) { throw new Error( - `'cleanupDelayMs' must be greater than 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `, + `'cleanupDelayMs' must be greater than or equal to 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `, ); } } diff --git a/libs/common/src/platform/state/user-key-definition.ts b/libs/common/src/platform/state/user-key-definition.ts index 7e845fc8585..503cd7b7828 100644 --- a/libs/common/src/platform/state/user-key-definition.ts +++ b/libs/common/src/platform/state/user-key-definition.ts @@ -30,9 +30,9 @@ export class UserKeyDefinition { throw new Error(`'deserializer' is a required property on key ${this.errorKeyName}`); } - if (options.cleanupDelayMs <= 0) { + if (options.cleanupDelayMs < 0) { throw new Error( - `'cleanupDelayMs' must be greater than 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `, + `'cleanupDelayMs' must be greater than or equal to 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `, ); }