( aggregates: DailyAggregate[], session: PracticedQueueSession, aggregatedIdsSet?: Set<string> )
| 89 | * insert — pass it across many calls to avoid recomputing from scratch. |
| 90 | */ |
| 91 | export function bucketSession( |
| 92 | aggregates: DailyAggregate[], |
| 93 | session: PracticedQueueSession, |
| 94 | aggregatedIdsSet?: Set<string> |
| 95 | ): boolean { |
| 96 | if (!session || !session.id) return false; |
| 97 | if (aggregatedIdsSet?.has(session.id)) return false; |
| 98 | const date = getLocalDateKey(session.startTime); |
| 99 | const kbId = session.kbId || UNKNOWN_KB_ID; |
| 100 | const bucket = findOrCreateBucket(aggregates, date, kbId); |
| 101 | if (bucket.ids.includes(session.id)) return false; |
| 102 | bucket.totalTime += session.totalTime || 0; |
| 103 | bucket.cardsCount += session.flashcardsCount || 0; |
| 104 | bucket.cardsTime += session.flashcardsTime || 0; |
| 105 | bucket.incRemsCount += session.incRemsCount || 0; |
| 106 | bucket.incRemsTime += session.incRemsTime || 0; |
| 107 | bucket.forgotCount += session.againCount || 0; |
| 108 | bucket.ids.push(session.id); |
| 109 | if (aggregatedIdsSet) aggregatedIdsSet.add(session.id); |
| 110 | return true; |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * Move sessions older than the raw-window into daily aggregates. Idempotent: |
no test coverage detected