1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-02 04:48:57 +02:00

Add derive option to clear state after cleanup (#7852)

Co-authored-by: Thomas Rittson <eliykat@users.noreply.github.com>
This commit is contained in:
Matt Gibson 2024-02-07 20:33:28 -05:00 committed by GitHub
parent 52c8cab152
commit 3371760779
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 1 deletions

View File

@ -48,6 +48,10 @@ type DeriveDefinitionOptions<TFrom, TTo, TDeps extends DerivedStateDependencies
* Defaults to 1000ms.
*/
cleanupDelayMs?: number;
/**
* Whether or not to clear the derived state when cleanup occurs. Defaults to true.
*/
clearOnCleanup?: boolean;
};
/**
@ -117,6 +121,10 @@ export class DeriveDefinition<TFrom, TTo, TDeps extends DerivedStateDependencies
return this.options.cleanupDelayMs < 0 ? 0 : this.options.cleanupDelayMs ?? 1000;
}
get clearOnCleanup() {
return this.options.clearOnCleanup ?? true;
}
buildCacheKey(): string {
return `derived_${this.stateDefinition.name}_${this.uniqueDerivationName}`;
}

View File

@ -144,6 +144,42 @@ describe("DefaultDerivedState", () => {
expect(parentState$.observed).toBe(false);
});
it("should clear state after cleanup", async () => {
const subscription = sut.state$.subscribe();
parentState$.next(newDate);
await awaitAsync();
expect(memoryStorage.internalStore[deriveDefinition.buildCacheKey()]).toEqual(
new Date(newDate),
);
subscription.unsubscribe();
// Wait for cleanup
await awaitAsync(cleanupDelayMs * 2);
expect(memoryStorage.internalStore[deriveDefinition.buildCacheKey()]).toBeUndefined();
});
it("should not clear state after cleanup if clearOnCleanup is false", async () => {
deriveDefinition.options.clearOnCleanup = false;
const subscription = sut.state$.subscribe();
parentState$.next(newDate);
await awaitAsync();
expect(memoryStorage.internalStore[deriveDefinition.buildCacheKey()]).toEqual(
new Date(newDate),
);
subscription.unsubscribe();
// Wait for cleanup
await awaitAsync(cleanupDelayMs * 2);
expect(memoryStorage.internalStore[deriveDefinition.buildCacheKey()]).toEqual(
new Date(newDate),
);
});
it("should not cleanup if there are still subscribers", async () => {
const subscription1 = sut.state$.subscribe();
const sub2Emissions: Date[] = [];

View File

@ -44,7 +44,15 @@ export class DefaultDerivedState<TFrom, TTo, TDeps extends DerivedStateDependenc
connector: () => {
return new ReplaySubject<TTo>(1);
},
resetOnRefCountZero: () => timer(this.deriveDefinition.cleanupDelayMs),
resetOnRefCountZero: () =>
timer(this.deriveDefinition.cleanupDelayMs).pipe(
concatMap(async () => {
if (this.deriveDefinition.clearOnCleanup) {
await this.memoryStorage.remove(this.storageKey);
}
return true;
}),
),
}),
);
}