From b2394978876526a3fbc3a03fcf77c26ca7b93b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Tue, 11 Mar 2025 14:48:52 -0400 Subject: [PATCH] achievement validation --- .../src/tools/achievements/event-processor.ts | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/libs/common/src/tools/achievements/event-processor.ts b/libs/common/src/tools/achievements/event-processor.ts index e9df09e6615..8b488b9f629 100644 --- a/libs/common/src/tools/achievements/event-processor.ts +++ b/libs/common/src/tools/achievements/event-processor.ts @@ -60,23 +60,31 @@ function validate( monitors$: Observable, status$: Observable, ): OperatorFunction { - // analyze the incoming event stream to identify achievements - const processor = pipe( + return pipe( withLatestFrom(monitors$), map(([action, monitors]) => { - // 🧩 TODO: transform list of monitors to the list of monitors triggered - // by the incoming action - return [action, monitors]; + // narrow the list of all live monitors to just those that may + // change the log + const triggered = monitors.filter((m) => m.filter(action)); + return [action, triggered] as const; }), withLatestFrom(status$), concatMap(([[action, monitors], status]) => { - // 🧩 TODO: execute each of the monitors feeding in its associated achievement - // entry and the action that triggered the achievement. - return from([] as AchievementFormat[]); + const results: AchievementFormat[] = []; + + // process achievement monitors sequentially, accumulating result records + for (const monitor of monitors) { + const statusEntry = status.find( + (s) => s.achievement.name === monitor.achievement && isProgress(s.achievement), + ); + results.push(...monitor.action(action, statusEntry)); + } + + // deliver results as a stream containing individual records to maintain + // the map/reduce model of the validator + return from(results); }), ); - - return processor; } const liveMonitors$ = achievementMonitors$.pipe(active(achievementsLog$));