import type { AllowanceState } from "./allowance.js"; import type { Notify } from "./notifications/index.js"; import type { BillingAdapter } from "./types.js"; /** Where a threshold was crossed. `key` is stable, and is what dedupe is keyed on. */ export interface AlertCrossing { key: "pack" | "pool" | "spend"; scope: "member" | "org"; threshold: number; unit: "percent" | "credits"; every: string; label: string | null; used: number; limit: number; percent: number; } export declare const DEFAULT_ALERT_THRESHOLDS: readonly [80, 100]; /** * Which thresholds this state is AT, highest first — pure, and knows nothing about what has * already been sent. * * Highest first because only the top one is worth an email: crossing 80 and 100 in the same * call is one piece of news ("you are out"), not two. */ export declare function crossings(state: Pick, thresholds?: readonly number[]): AlertCrossing[]; /** * Filter to the crossings nobody has been told about, and record them. * * Read-modify-write, and NOT transactional — two concurrent calls can both decide to send. * That is deliberate and safe: every notification carries a derived id * (`alert::::`), so a receiver deduping on it turns the race * into one email. Locking a metered call to avoid a rare duplicate would be the wrong trade * by a wide margin. */ export declare function claimCrossings(adapter: BillingAdapter, input: { orgId: string; memberId?: string | null; cycleKey: string; crossings: AlertCrossing[]; }): Promise; /** * The whole thing, as the meter calls it: notice, claim, say. Never awaited by the caller. * * Failures are swallowed here rather than at the meter, for the reason every notification * follows: the call this describes already happened and was already charged. */ export declare function maybeAlert(adapter: BillingAdapter, notify: Notify | undefined, input: { orgId: string; memberId?: string | null; cycleKey: string; state: Pick; thresholds?: readonly number[]; }): void; //# sourceMappingURL=alerts.d.ts.map