//#region src/index.d.ts
/**
 * `@platform-modules/notifications` — multi-channel delivery seam (zero channel code).
 */
/** Mirrors `@platform-modules/jobs` `IdempotencyStore` — host wires one store to both. */
interface DedupStore {
  seen(key: string): Promise<boolean>;
  mark(key: string, ttl?: number): Promise<void>;
}
interface PreferenceStore {
  getEnabledChannels(userId: string, eventType: string): Promise<string[]>;
}
type NotifyEvent = {
  id?: string;
  type: string;
  userId: string;
  dedupKey?: string;
  template: {
    subject?: string;
    body: string;
    html?: string;
  };
  data: Record<string, string>;
  recipients: Record<string, unknown>;
};
type RenderedMessage = {
  subject?: string;
  body: string;
  html?: string;
};
type ChannelError = {
  message: string;
  retryable?: boolean;
  code?: string;
};
type ChannelResult = {
  ok: true;
  id?: string;
} | {
  ok: false;
  error: ChannelError;
};
interface ChannelAdapter {
  channel: string;
  send(rendered: RenderedMessage, recipient: unknown): Promise<ChannelResult>;
  supports?(event: NotifyEvent): boolean;
}
type DeliveryResult = {
  channel: string;
  status: 'sent' | 'skipped' | 'deduped' | 'failed';
  id?: string;
  error?: ChannelError;
};
type NotifyContext = {
  adapters: ChannelAdapter[];
  preferences: PreferenceStore;
  dedup: DedupStore;
  /**
   * Wraps a per-channel delivery attempt. Within-call idempotence is a local
   * per-channel success flag (independent of the store): once an attempt
   * succeeds, further attempts short-circuit — so a retry after a successful
   * first attempt does not double-deliver, even for an unkeyed event. The
   * persistent dedup record is written on success only, so a retry after a
   * FAILED first attempt re-sends.
   */
  retry?: (attempt: () => Promise<ChannelResult>) => Promise<ChannelResult>;
};
/** Zero-dep `{{key}}` interpolation — missing keys become empty strings. */
declare function render(tpl: string, data: Record<string, string>): string;
declare function deriveDedupKey(event: NotifyEvent, channel: string, recipientKey: string): string | null;
declare function resolvePreferences(store: PreferenceStore, userId: string, eventType: string): Promise<string[]>;
declare function notify(event: NotifyEvent, ctx: NotifyContext): Promise<DeliveryResult[]>;
//#endregion
export { ChannelAdapter, ChannelError, ChannelResult, DedupStore, DeliveryResult, NotifyContext, NotifyEvent, PreferenceStore, RenderedMessage, deriveDedupKey, notify, render, resolvePreferences };