import type { CounterKind, Totals } from "./counters-do"; type Row = { key: string; a: number; b: number; c: number }; type CounterStub = { add(kind: CounterKind, scope: string, key: string, delta: Totals, meta: string | null): Promise; }; /** * Adds what each flushed row gained since its last flush (its `base_*` columns) to a platform total in another * Counters object, per key. Best effort: a lost forward only skews a platform safety net, never a bill. */ export async function forwardFlushed( sql: SqlStorage, namespace: DurableObjectNamespace, target: { kind: CounterKind; scope: string }, rows: Row[], ): Promise { const deltas = rows.flatMap((row) => { const base = sql .exec<{ base_a: number | null; base_b: number | null; base_c: number | null }>( "SELECT base_a, base_b, base_c FROM counters WHERE key = ?", row.key, ) .toArray()[0]; const delta: Totals = [row.a - (base?.base_a ?? 0), row.b - (base?.base_b ?? 0), row.c - (base?.base_c ?? 0)]; return delta.some((value) => value !== 0) ? [{ key: row.key, delta }] : []; }); if (deltas.length === 0) return; const stub = namespace.get(namespace.idFromName(`${target.kind}:${target.scope}`)) as unknown as CounterStub; await Promise.all( deltas.map(({ key, delta }) => stub .add(target.kind, target.scope, key, delta, null) .catch((error: unknown) => console.warn("Counter forward failed", target, key, error)), ), ); }