1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 05:30:01 +00:00

tweak return types

This commit is contained in:
✨ Audrey ✨
2025-03-17 17:25:32 -04:00
parent 5eb4c2b7e2
commit 7699752390
3 changed files with 44 additions and 30 deletions

View File

@@ -1,8 +1,17 @@
import { Observable, ReplaySubject, Subject, debounceTime, filter, map, startWith } from "rxjs";
import {
Observable,
ReplaySubject,
Subject,
debounceTime,
filter,
map,
share,
startWith,
} from "rxjs";
import { active } from "./achievement-manager";
import { achievements } from "./achievement-processor";
import { latestEarnedSet, latestMetrics } from "./latest-metrics";
import { latestEarnedMetrics, latestProgressMetrics } from "./latest-metrics";
import { isEarnedEvent, isProgressEvent } from "./meta";
import {
AchievementEarnedEvent,
@@ -26,30 +35,35 @@ export class AchievementHub {
this.achievementLog = new ReplaySubject<AchievementEvent>(bufferSize);
this.achievements.subscribe(this.achievementLog);
const active$ = validators$.pipe(active(this.metrics$(), this.earned$()));
const metrics$ = this.metrics$().pipe(
map((m) => new Map(Array.from(m.entries(), ([k, v]) => [k, v.achievement.value] as const))),
share(),
);
const earned$ = this.earned$().pipe(map((m) => new Set(m.keys())));
const active$ = validators$.pipe(active(metrics$, earned$));
events$.pipe(achievements(active$, this.metrics$())).subscribe(this.achievements);
events$.pipe(achievements(active$, metrics$)).subscribe(this.achievements);
}
private readonly achievements: Subject<AchievementEvent>;
private readonly achievementLog: ReplaySubject<AchievementEvent>;
earned$(): Observable<Set<AchievementId>> {
earned$(): Observable<Map<AchievementId, AchievementEarnedEvent>> {
return this.achievementLog.pipe(
filter((e) => isEarnedEvent(e)),
map((e) => e as AchievementEarnedEvent),
latestEarnedSet(),
startWith(new Set<AchievementId>()),
latestEarnedMetrics(),
startWith(new Map<AchievementId, AchievementEarnedEvent>()),
debounceTime(ACHIEVEMENT_INITIAL_DEBOUNCE_MS),
);
}
metrics$(): Observable<Map<MetricId, number>> {
metrics$(): Observable<Map<MetricId, AchievementProgressEvent>> {
return this.achievementLog.pipe(
filter((e) => isProgressEvent(e)),
map((e) => e as AchievementProgressEvent),
latestMetrics(),
startWith(new Map<MetricId, number>()),
latestProgressMetrics(),
startWith(new Map<MetricId, AchievementProgressEvent>()),
);
}

View File

@@ -6,7 +6,7 @@ import {
ItemCreatedProgress2Event,
} from "./examples/achievement-events";
import { CredentialGeneratedProgress, ItemCreatedProgress } from "./examples/example-validators";
import { latestMetrics } from "./latest-metrics";
import { latestProgressMetrics } from "./latest-metrics";
import { AchievementProgressEvent, MetricId } from "./types";
describe("latestMetrics", () => {
@@ -14,7 +14,7 @@ describe("latestMetrics", () => {
const subject = new Subject<AchievementProgressEvent>();
const result = new BehaviorSubject(new Map<MetricId, number>());
subject.pipe(latestMetrics()).subscribe(result);
subject.pipe(latestProgressMetrics()).subscribe(result);
subject.next(ItemCreatedProgressEvent);
expect(result.value.get(ItemCreatedProgress)).toEqual(
@@ -26,7 +26,7 @@ describe("latestMetrics", () => {
const subject = new Subject<AchievementProgressEvent>();
const result = new BehaviorSubject(new Map<MetricId, number>());
subject.pipe(latestMetrics()).subscribe(result);
subject.pipe(latestProgressMetrics()).subscribe(result);
subject.next(ItemCreatedProgressEvent);
subject.next(CredentialGeneratedProgressEvent);
@@ -42,7 +42,7 @@ describe("latestMetrics", () => {
const subject = new Subject<AchievementProgressEvent>();
const result = new BehaviorSubject(new Map<MetricId, number>());
subject.pipe(latestMetrics()).subscribe(result);
subject.pipe(latestProgressMetrics()).subscribe(result);
subject.next(ItemCreatedProgressEvent);
subject.next(ItemCreatedProgress2Event);
@@ -55,7 +55,7 @@ describe("latestMetrics", () => {
const subject = new Subject<AchievementProgressEvent>();
const result = new BehaviorSubject(new Map<MetricId, number>());
subject.pipe(latestMetrics()).subscribe(result);
subject.pipe(latestProgressMetrics()).subscribe(result);
subject.next(ItemCreatedProgress2Event);
subject.next(ItemCreatedProgressEvent);

View File

@@ -31,36 +31,36 @@ function latestProgressEvents(): OperatorFunction<
);
}
function latestMetrics(): OperatorFunction<AchievementProgressEvent, Map<MetricId, number>> {
function latestProgressMetrics(): OperatorFunction<
AchievementProgressEvent,
Map<MetricId, AchievementProgressEvent>
> {
return pipe(
scan((metrics, captured) => {
const [timestamp] = metrics.get(captured.achievement.name) ?? [];
const metric = metrics.get(captured.achievement.name);
// omit stale metrics
if (timestamp && timestamp > captured["@timestamp"]) {
if (metric && metric["@timestamp"] > captured["@timestamp"]) {
return metrics;
}
const latest = [captured["@timestamp"], captured.achievement.value] as const;
metrics.set(captured.achievement.name, latest);
metrics.set(captured.achievement.name, captured);
return metrics;
}, new Map<MetricId, readonly [number, number]>()),
// omit timestamps from metrics
map(
(metrics) => new Map(Array.from(metrics.entries(), ([metric, [, value]]) => [metric, value])),
),
}, new Map<MetricId, AchievementProgressEvent>()),
);
}
function latestEarnedSet(): OperatorFunction<AchievementEarnedEvent, Set<AchievementId>> {
function latestEarnedMetrics(): OperatorFunction<
AchievementEarnedEvent,
Map<AchievementId, AchievementEarnedEvent>
> {
return pipe(
scan((earned, captured) => {
earned.add(captured.achievement.name);
earned.set(captured.achievement.name, captured);
return earned;
}, new Set<AchievementId>()),
}, new Map<AchievementId, AchievementEarnedEvent>()),
);
}
export { latestMetrics, latestProgressEvents, latestEarnedSet };
export { latestProgressMetrics, latestProgressEvents, latestEarnedMetrics };