| 1 | import { |
| 2 | PullRequestDiffStat, |
| 3 | PullRequestListStatsInput, |
| 4 | type PullRequestListStatsResult, |
| 5 | type PullRequestRef, |
| 6 | } from "@t3tools/contracts"; |
| 7 | import * as Effect from "effect/Effect"; |
| 8 | import * as Option from "effect/Option"; |
| 9 | import * as Schema from "effect/Schema"; |
| 10 | import { persistQuery, type QueryPersistence } from "./queryPersistence.ts"; |
| 11 | |
| 12 | const requestKey = Schema.fromJsonString(Schema.Tuple([Schema.String, PullRequestListStatsInput])); |
| 13 | const statKey = (ref: PullRequestRef) => |
| 14 | JSON.stringify(["pull-request-stat", ref.projectId, ref.host ?? "", ref.repository, ref.number]); |
| 15 | |
| 16 | /** Visible rows are batched differently after a restart, so store their counts individually. */ |
| 17 | export function persistPullRequestStats(): QueryPersistence<PullRequestListStatsResult> { |
| 18 | const row = persistQuery(PullRequestDiffStat); |
| 19 | return { |
| 20 | load: (environmentId, key) => |
| 21 | Effect.gen(function* () { |
| 22 | const [, input] = yield* Schema.decodeEffect(requestKey)(key); |
| 23 | const rows = yield* Effect.forEach(input.refs, (ref) => |
| 24 | row.load(environmentId, statKey(ref)), |
| 25 | ); |
| 26 | const stats = rows.flatMap((value) => (Option.isSome(value) ? [value.value] : [])); |
| 27 | return stats.length ? Option.some({ stats }) : Option.none(); |
| 28 | }).pipe(Effect.orElseSucceed(() => Option.none())), |
| 29 | save: (environmentId, key, result) => |
| 30 | Effect.gen(function* () { |
| 31 | const [, input] = yield* Schema.decodeEffect(requestKey)(key); |
| 32 | yield* Effect.forEach(result.stats, (stat) => { |
| 33 | const ref = input.refs.find( |
| 34 | (ref) => |
| 35 | ref.projectId === stat.projectId && |
| 36 | ref.repository === stat.repository && |
| 37 | ref.number === stat.number, |
| 38 | ); |
| 39 | return ref ? row.save(environmentId, statKey(ref), stat) : Effect.void; |
| 40 | }); |
| 41 | }).pipe(Effect.ignore), |
| 42 | }; |
| 43 | } |