import { LeaderServiceOptions } from './leader';
export type MeshBroadcastMap = Record<string, unknown>;
export interface MeshBroadcastOptions {
    skipSelf?: boolean;
}
/** Generation-pinned execution context for mesh broadcast handlers. */
export interface MeshHandlerContext {
    /**
     * Aborted synchronously when the owning MeshService generation is stopped
     * or fenced. Existing handlers may ignore this signal.
     */
    signal: AbortSignal;
}
export interface MeshNode {
    instanceId: number;
    hostname: string;
    self: boolean;
    processId?: string;
    linkEndpointId?: string;
    /** v2 mesh-link Ed25519 public key (SPKI DER, base64) pinned by peers. */
    linkEndpointPublicKey?: string;
    linkUrl?: string;
    startedAt?: number;
}
export interface MeshServiceOptions {
    heartbeatIntervalMs?: number;
    nodeTtlMs?: number;
    leaderOptions?: LeaderServiceOptions;
    nodeMetadata?: Omit<MeshNode, 'instanceId' | 'hostname' | 'self'>;
    maxMessageBytes?: number;
    /** Maximum concurrently processed incoming broadcasts. */
    maxActiveHandlers?: number;
    /** Maximum bytes retained by concurrently processed incoming broadcasts. */
    maxActiveHandlerBytes?: number;
    /** Maximum Redis list/set members touched by one mesh cleanup Lua call. */
    cleanupBatchSize?: number;
}
export declare class MeshBroadcastIndeterminateDeliveryError extends Error {
    constructor(type: string, cause?: unknown);
}
export declare function destroyMeshRedis(): void;
export declare class MeshService<B extends MeshBroadcastMap = {}> {
    private _instanceId;
    private key;
    private prefix;
    private running;
    private heartbeatIntervalMs;
    private nodeTtlMs;
    private maxMessageBytes;
    private maxActiveHandlers;
    private maxActiveHandlerBytes;
    private cleanupBatchSize;
    private leaderOptions?;
    private nodeMetadata;
    private heartbeatTimer;
    private leaderService;
    /** Changes on every acquire/loss, including reacquisition by one object. */
    private leaderEpoch;
    private subscriberClient;
    private broadcastHandlers;
    private broadcastGeneration;
    private activeIncomingMessages;
    private activeIncomingBytes;
    private nodeCleanedUpCallback;
    private leaseLostCallback;
    private leaseLost;
    private heartbeatGeneration;
    private readonly cleanupDrains;
    private leaseSafeUntil;
    private leaseSafetyTimer;
    private lifecycle;
    private generation;
    private leaseFencePromise?;
    /** @internal Overridable by focused lifecycle tests. */
    private leaseLossCallbackTimeoutMs;
    private logger;
    constructor(key: string, options?: MeshServiceOptions);
    get instanceId(): number;
    registerBroadcastHandler<K extends keyof B & string>(type: K, handler: (data: B[K], senderInstanceId: number, context: MeshHandlerContext) => void | Promise<void>): void;
    setNodeCleanedUpCallback(cb: (instanceId: number) => void | Promise<void>): void;
    /** Fires once after renewal proves this instance is no longer a member. */
    setLeaseLostCallback(cb: (reason?: Error) => void | Promise<void>): void;
    /**
     * Synchronously fences work once the last conservatively-known membership
     * lease can no longer be valid.
     */
    assertLeaseSafe(): void;
    /**
     * @internal Synchronously revokes this generation's membership authority
     * and handler state. Physical Redis/subscriber shutdown continues
     * asynchronously and the returned promise settles after lease-loss
     * callbacks finish.
     */
    fence(reason: Error): Promise<void>;
    getNodes(): Promise<MeshNode[]>;
    getNode(instanceId: number): Promise<MeshNode | undefined>;
    updateNodeMetadata(metadata: Omit<MeshNode, 'instanceId' | 'hostname' | 'self'>): Promise<void>;
    broadcast<K extends keyof B & string>(type: K, data: B[K], options?: MeshBroadcastOptions): Promise<void>;
    start(): Promise<void>;
    private startImpl;
    stop(): Promise<void>;
    private stopImpl;
    private runLifecycle;
    private discardBroadcastGeneration;
    private scheduleIncomingMessage;
    private encodeEnvelope;
    /** @internal Overridable by focused broadcast-delivery tests. */
    private getPublisher;
    private validateIncomingSender;
    private nextIdKey;
    private serializeNode;
    private parseNode;
    private heartbeatsKey;
    private nodesKey;
    private cleanupKey;
    private cleanupProcessingKey;
    private broadcastChannel;
    private doHeartbeat;
    private startCleanup;
    private doCleanup;
    private scheduleCleanupContinuation;
    private fenceLeaseLoss;
    private armLeaseSafetyTimer;
    private clearLeaseSafetyTimer;
    private handleBroadcastIncoming;
    private handleBroadcastMessage;
}
//# sourceMappingURL=mesh.d.ts.map