mirror of
https://github.com/bitwarden/browser
synced 2026-02-26 17:43:22 +00:00
even more cleanup
This commit is contained in:
@@ -2,6 +2,7 @@ import { UserId } from "../../types/guid";
|
||||
|
||||
import { AchievementEarnedEvent, AchievementId, AchievementProgressEvent, MetricId } from "./types";
|
||||
|
||||
// FIXME: see <./types.ts> AchievementValidator
|
||||
export function progressEvent(name: MetricId, value: number = 1): AchievementProgressEvent {
|
||||
return {
|
||||
"@timestamp": Date.now(),
|
||||
@@ -25,6 +26,7 @@ export function progressEvent(name: MetricId, value: number = 1): AchievementPro
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: see <./types.ts> AchievementValidator
|
||||
export function earnedEvent(name: AchievementId): AchievementEarnedEvent {
|
||||
return {
|
||||
"@timestamp": Date.now(),
|
||||
|
||||
@@ -97,9 +97,4 @@ export class AchievementHub {
|
||||
startWith(new Map<MetricId, AchievementProgressEvent>()),
|
||||
);
|
||||
}
|
||||
|
||||
//Test methods
|
||||
addEvent(event: AchievementEvent) {
|
||||
this.achievementLog.next(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { SendItemCreatedCountConfig } from "./validators/config/send-created-cou
|
||||
import { SendItemCreatedCountValidator } from "./validators/send-item-created-count-validator";
|
||||
import { VaultItemCreatedCountValidator } from "./validators/vault-item-created-count-validator";
|
||||
|
||||
export class NextAchievementService implements AchievementService {
|
||||
export class DefaultAchievementService implements AchievementService {
|
||||
constructor(private readonly collector: UserEventCollector) {}
|
||||
|
||||
private hubs = new Map<string, AchievementHub>();
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { AchievementEarnedEvent, AchievementProgressEvent, UserActionEvent } from "./types";
|
||||
|
||||
export abstract class EventStoreAbstraction {
|
||||
abstract events$: Observable<UserActionEvent | AchievementProgressEvent | AchievementEarnedEvent>;
|
||||
abstract addEvent(
|
||||
event: UserActionEvent | AchievementProgressEvent | AchievementEarnedEvent,
|
||||
): boolean;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Observable, Subject } from "rxjs";
|
||||
|
||||
import { EventStoreAbstraction } from "./event-store.abstraction.service";
|
||||
import { AchievementEarnedEvent, AchievementProgressEvent } from "./types";
|
||||
|
||||
// Will be replaced by the achievementHub
|
||||
export class EventStore implements EventStoreAbstraction {
|
||||
private _events = new Subject<AchievementProgressEvent | AchievementEarnedEvent>();
|
||||
|
||||
events$: Observable<AchievementProgressEvent | AchievementEarnedEvent> =
|
||||
this._events.asObservable();
|
||||
|
||||
constructor() {}
|
||||
|
||||
addEvent(event: AchievementProgressEvent | AchievementEarnedEvent): boolean {
|
||||
// FIXME Collapse existing of same metric/higher count AchievementProgressEvents
|
||||
//eslint-disable-next-line no-console
|
||||
console.log("EventStore.addEvent", event);
|
||||
this._events.next(event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
import { Achievement, AchievementEvent, AchievementValidator, UserActionEvent } from "./types";
|
||||
|
||||
// sync data from the server (consumed by event store)
|
||||
const replicationIn$ = new Subject<AchievementEvent>();
|
||||
|
||||
// data incoming from the UI (consumed by validator)
|
||||
const userActionIn$ = new Subject<UserActionEvent>();
|
||||
|
||||
// what to look for (consumed by validator)
|
||||
const achievementMonitors$ = new Subject<AchievementValidator[]>();
|
||||
|
||||
// data stored in local state (consumed by validator and achievement list)
|
||||
const achievementsLocal$ = new Subject<AchievementEvent[]>();
|
||||
|
||||
// metadata (consumed by achievement list)
|
||||
const achievementMetadata$ = new Subject<Achievement>();
|
||||
|
||||
export {
|
||||
replicationIn$,
|
||||
userActionIn$,
|
||||
achievementsLocal$,
|
||||
achievementMonitors$,
|
||||
achievementMetadata$,
|
||||
};
|
||||
@@ -21,49 +21,67 @@ export type AchievementEarnedEvent = EventFormat &
|
||||
export type AchievementEvent = AchievementProgressEvent | AchievementEarnedEvent;
|
||||
|
||||
type MetricCriteria = {
|
||||
// the metric observed by low/high triggers
|
||||
/** the metric observed by low/high triggers */
|
||||
metric: MetricId;
|
||||
} & RequireAtLeastOne<{
|
||||
// criteria fail when the metric is less than or equal to `low`
|
||||
/** criteria fail when the metric is less than or equal to `low` */
|
||||
low: number;
|
||||
// criteria fail when the metric is greater than `high`
|
||||
/** criteria fail when the metric is greater than `high` */
|
||||
high: number;
|
||||
}>;
|
||||
type ActiveCriteria = "until-earned" | MetricCriteria;
|
||||
|
||||
// consumed by validator and achievement list (should this include a "toast-alerter"?)
|
||||
/** consumed by validator and achievement list (should this include a "toast-alerter"?) */
|
||||
export type Achievement = {
|
||||
// identifies the achievement being monitored
|
||||
/** identifies the achievement being monitored */
|
||||
achievement: AchievementId;
|
||||
|
||||
// human-readable name of the achievement
|
||||
/** human-readable name of the achievement */
|
||||
name: string;
|
||||
|
||||
// human-readable description of the achievement
|
||||
/** human-readable description of the achievement */
|
||||
description?: string;
|
||||
|
||||
// conditions that determine when the achievement validator should be loaded
|
||||
// by the processor
|
||||
/* conditions that determine when the achievement validator should be loaded
|
||||
* by the processor
|
||||
*/
|
||||
active: ActiveCriteria;
|
||||
|
||||
// identifies the validator containing filter/measure/earn methods
|
||||
/** identifies the validator containing filter/measure/earn methods */
|
||||
validator: ValidatorId;
|
||||
|
||||
// whether or not the achievement is hidden until it is earned
|
||||
/** whether or not the achievement is hidden until it is earned */
|
||||
hidden: boolean;
|
||||
};
|
||||
|
||||
// consumed by validator
|
||||
/** An achievement completion monitor */
|
||||
//
|
||||
// FIXME:
|
||||
// * inject a monitor/capture interface into measure and rewards
|
||||
// * this interface contains methods from <./achievement-events.ts>
|
||||
// * it constructs context-specific events, filling in device/time/etc
|
||||
export type AchievementValidator = Achievement & {
|
||||
// when the watch triggers on incoming user events
|
||||
trigger: (item: UserActionEvent) => boolean;
|
||||
/** when the watch triggers on incoming user events
|
||||
* @param event a monitored user action event
|
||||
* @returns true when the validator should process the event, otherwise false.
|
||||
*/
|
||||
trigger: (event: UserActionEvent) => boolean;
|
||||
|
||||
// observe data from the event stream and produces measurements
|
||||
measure?: (item: UserActionEvent, metrics: Map<MetricId, number>) => AchievementProgressEvent[];
|
||||
/** observes data from the event stream and produces measurements;
|
||||
* this runs after the event is triggered.
|
||||
* @param event a monitored user action event
|
||||
* @returns a collection of measurements extracted from the event (may be empty)
|
||||
*/
|
||||
measure?: (event: UserActionEvent, metrics: Map<MetricId, number>) => AchievementProgressEvent[];
|
||||
|
||||
// monitors achievement progress and emits earned achievements
|
||||
/** monitors achievement progress and emits earned achievements;
|
||||
* this runs after all measurements are taken.
|
||||
* @param progress events emitted by `measure`. If `measure` is undefined, this is an empty array.
|
||||
* @param metrics last-recorded progress value for all achievement metrics
|
||||
* @returns a collection of achievements awarded by the event.
|
||||
*/
|
||||
award?: (
|
||||
events: AchievementProgressEvent[],
|
||||
progress: AchievementProgressEvent[],
|
||||
metrics: Map<MetricId, number>,
|
||||
) => AchievementEarnedEvent[];
|
||||
};
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { ItemCreatedProgressEvent } from "./examples/achievement-events";
|
||||
import { ItemCreatedProgress } from "./examples/example-validators";
|
||||
import { mapProgressByName } from "./util";
|
||||
|
||||
describe("mapProgressByName", () => {
|
||||
it("creates a map containing a progress value", () => {
|
||||
const result = mapProgressByName([ItemCreatedProgressEvent]);
|
||||
|
||||
expect(result.get(ItemCreatedProgress)).toEqual(ItemCreatedProgressEvent.achievement.value);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { isProgressEvent } from "./meta";
|
||||
import { AchievementEvent } from "./types";
|
||||
|
||||
export function mapProgressByName(status: AchievementEvent[]) {
|
||||
return new Map(
|
||||
status.filter(isProgressEvent).map((e) => [e.achievement.name, e.achievement.value] as const),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user