/**
 * Reminder dismissed/snoozed state — shared across devices.
 *
 * The alarm subsystem (client/components/alarms.ts) keys every reminder by a
 * per-occurrence string (`providerId:startMs[@offsetMs]` for calendar,
 * `taskUuid:dueMs` for tasks). Those keys are built from Google-stable ids,
 * so the SAME occurrence produces the SAME key on every device — which is
 * what makes cross-device sync meaningful: dismiss a reminder on the desktop
 * and the laptop's poller sees the dismissal before it fires its own popup.
 *
 * State lives in `reminders.jsonc` in the shared GDrive folder (same rails
 * as allowlist.jsonc / userdict.csv). Values are epoch-ms timestamps:
 *   dismissed[key] = when the user dismissed it   (retention: 30 days)
 *   snoozed[key]   = fire again after this time   (retention: 7 days past)
 *
 * Merge is per-key max — a dismissal or longer snooze on ANY device wins.
 * Deletions don't propagate (union semantics); the only deletion in the
 * alarm flow is the Open-button re-evaluate, which by construction touches
 * a key that was never pushed as dismissed. Timestamps double as the prune
 * criterion so the file can't grow forever.
 *
 * This module is dependency-free (mailx-types) so the desktop service
 * (mailx-settings) and the Android/web service (mailx-store-web) share one
 * merge implementation.
 */
export interface ReminderState {
    /** occurrence-key → epoch-ms when dismissed */
    dismissed: Record<string, number>;
    /** occurrence-key → epoch-ms snooze-until */
    snoozed: Record<string, number>;
}
export declare const REMINDER_STATE_FILE = "reminders.jsonc";
/** Coerce arbitrary parsed JSON (or the client's localStorage maps, whose
 *  legacy dismissed values are boolean `true`) into a clean ReminderState.
 *  Legacy booleans become `now` so they get a full retention window. */
export declare function normalizeReminderState(raw: any, now: number): ReminderState;
/** Union merge with per-key max, pruned by retention. Inputs must already
 *  be normalized. Pure — does not mutate its arguments. */
export declare function mergeReminderStates(a: ReminderState, b: ReminderState, now: number): ReminderState;
/** Deep-equal for change detection so a no-op merge skips the cloud write. */
export declare function reminderStatesEqual(a: ReminderState, b: ReminderState): boolean;
//# sourceMappingURL=reminder-state.d.ts.map