import type { AgenticHub } from "../channel/index.ts"; import type { PresenceRow, PresenceStore } from "./store.ts"; export interface PresenceFamilyOptions { /** * How often to age out stale presence rows, in ms. Default: a third of the * store's TTL. Pass 0 to disable the internal timer (tests call * {@link PresenceFamilyHandle.sweepNow} explicitly). The sweep reads "now" * from the store's own clock, so liveness time has a single source of truth. */ sweepIntervalMs?: number; /** * Notified of a fault this module handles while keeping the connection: a * malformed presence payload ({@link PresencePayloadError}), a rejected * ownership takeover ({@link PresenceOwnershipError}), or a presence-sweep * error. Other handler exceptions are not routed here — they propagate to * {@link AgenticHub} and surface via the hub's own error handling. */ onError?: (err: unknown, connectionId?: string) => void; } /** Handle to the attached presence family — drives/stops the presence sweep. */ export interface PresenceFamilyHandle { /** Age out stale presence rows now and return the removed rows. */ sweepNow(): PresenceRow[]; /** Stop the presence sweep timer. */ stop(): void; } /** A malformed presence payload rejected before it touches the store. */ export declare class PresencePayloadError extends Error { readonly family: string; constructor(family: string, detail: string); } /** * Attach the presence family (`register`/`heartbeat`/`deregister`) to `hub`, * backed by `store`. Registers three handlers via the S1 seam and schedules the * presence-TTL sweep. Returns a handle to drive/stop the sweep. * * @throws DuplicateFamilyHandlerError if one of the three families already has * a handler on this hub (one family, one owning module). */ export declare function attachPresenceFamily(hub: AgenticHub, store: PresenceStore, options?: PresenceFamilyOptions): PresenceFamilyHandle;