/** * Shapes merged daily totals into the per-day provider stacks both chart * implementations (Swift Charts on iOS, plain views elsewhere) render. * * @module usageChartData */import type { UsageProviderKind } from "@t3tools/contracts";import type { DailyTotals } from "@t3tools/shared/usageMerge"; import { PROVIDER_ORDER } from "./usageProviders"; export type UsageChartMetric = "cost" | "tokens"; export interface UsageChartDay { readonly day: string; /** In {@link PROVIDER_ORDER}, i.e. bottom of the stack first. */ readonly values: readonly { readonly provider: UsageProviderKind; readonly value: number }[]; readonly total: number;} /** One entry per day in the window, zero-filled where nothing happened. */export function buildChartDays( days: readonly string[], daily: readonly DailyTotals[], metric: UsageChartMetric,): readonly UsageChartDay[] { const byDay = new Map(daily.map((totals) => [totals.day, totals])); return days.map((day) => { const totals = byDay.get(day); const values = PROVIDER_ORDER.map((provider) => { const entry = totals?.byProvider.get(provider); const value = entry === undefined ? 0 : metric === "cost" ? entry.costUsd : entry.totalTokens; return { provider, value }; }); return { day, values, total: values.reduce((sum, entry) => sum + entry.value, 0), }; });}
/**
* Shapes merged daily totals into the per-day provider stacks both chart
* implementations (Swift Charts on iOS, plain views elsewhere) render.
*
* @module usageChartData
*/
import type { UsageProviderKind } from "@t3tools/contracts";
import type { DailyTotals } from "@t3tools/shared/usageMerge";
import { PROVIDER_ORDER } from "./usageProviders";
export type UsageChartMetric = "cost" | "tokens";
export interface UsageChartDay {
readonly day: string;
/** In {@link PROVIDER_ORDER}, i.e. bottom of the stack first. */
readonly values: readonly { readonly provider: UsageProviderKind; readonly value: number }[];
readonly total: number;
}
/** One entry per day in the window, zero-filled where nothing happened. */
export function buildChartDays(
days: readonly string[],
daily: readonly DailyTotals[],
metric: UsageChartMetric,
): readonly UsageChartDay[] {
const byDay = new Map(daily.map((totals) => [totals.day, totals]));
return days.map((day) => {
const totals = byDay.get(day);
const values = PROVIDER_ORDER.map((provider) => {
const entry = totals?.byProvider.get(provider);
const value = entry === undefined ? 0 : metric === "cost" ? entry.costUsd : entry.totalTokens;
return { provider, value };
});
return {
day,
values,
total: values.reduce((sum, entry) => sum + entry.value, 0),
};
});
}