From 7699752390ab3ecd7deda93023b898da15f42667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Mon, 17 Mar 2025 17:25:32 -0400 Subject: [PATCH] tweak return types --- .../src/tools/achievements/achievement-hub.ts | 34 +++++++++++++------ .../tools/achievements/latest-metrics.spec.ts | 10 +++--- .../src/tools/achievements/latest-metrics.ts | 30 ++++++++-------- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/libs/common/src/tools/achievements/achievement-hub.ts b/libs/common/src/tools/achievements/achievement-hub.ts index 50c4d4a164e..90faa7189e7 100644 --- a/libs/common/src/tools/achievements/achievement-hub.ts +++ b/libs/common/src/tools/achievements/achievement-hub.ts @@ -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(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; private readonly achievementLog: ReplaySubject; - earned$(): Observable> { + earned$(): Observable> { return this.achievementLog.pipe( filter((e) => isEarnedEvent(e)), map((e) => e as AchievementEarnedEvent), - latestEarnedSet(), - startWith(new Set()), + latestEarnedMetrics(), + startWith(new Map()), debounceTime(ACHIEVEMENT_INITIAL_DEBOUNCE_MS), ); } - metrics$(): Observable> { + metrics$(): Observable> { return this.achievementLog.pipe( filter((e) => isProgressEvent(e)), map((e) => e as AchievementProgressEvent), - latestMetrics(), - startWith(new Map()), + latestProgressMetrics(), + startWith(new Map()), ); } diff --git a/libs/common/src/tools/achievements/latest-metrics.spec.ts b/libs/common/src/tools/achievements/latest-metrics.spec.ts index 84171a5df80..a7c4fe3043c 100644 --- a/libs/common/src/tools/achievements/latest-metrics.spec.ts +++ b/libs/common/src/tools/achievements/latest-metrics.spec.ts @@ -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(); const result = new BehaviorSubject(new Map()); - 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(); const result = new BehaviorSubject(new Map()); - 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(); const result = new BehaviorSubject(new Map()); - 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(); const result = new BehaviorSubject(new Map()); - subject.pipe(latestMetrics()).subscribe(result); + subject.pipe(latestProgressMetrics()).subscribe(result); subject.next(ItemCreatedProgress2Event); subject.next(ItemCreatedProgressEvent); diff --git a/libs/common/src/tools/achievements/latest-metrics.ts b/libs/common/src/tools/achievements/latest-metrics.ts index e32fb400d55..5353e9ba360 100644 --- a/libs/common/src/tools/achievements/latest-metrics.ts +++ b/libs/common/src/tools/achievements/latest-metrics.ts @@ -31,36 +31,36 @@ function latestProgressEvents(): OperatorFunction< ); } -function latestMetrics(): OperatorFunction> { +function latestProgressMetrics(): OperatorFunction< + AchievementProgressEvent, + Map +> { 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()), - - // omit timestamps from metrics - map( - (metrics) => new Map(Array.from(metrics.entries(), ([metric, [, value]]) => [metric, value])), - ), + }, new Map()), ); } -function latestEarnedSet(): OperatorFunction> { +function latestEarnedMetrics(): OperatorFunction< + AchievementEarnedEvent, + Map +> { return pipe( scan((earned, captured) => { - earned.add(captured.achievement.name); + earned.set(captured.achievement.name, captured); return earned; - }, new Set()), + }, new Map()), ); } -export { latestMetrics, latestProgressEvents, latestEarnedSet }; +export { latestProgressMetrics, latestProgressEvents, latestEarnedMetrics };