mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 05:30:01 +00:00
tweak return types
This commit is contained in:
@@ -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>()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user