import { MeshService, type MeshBroadcastMap, type MeshBroadcastOptions, type MeshServiceOptions } from '../mesh';
import { MeshClientRegistry } from './mesh-client-registry';
import { type MeshClientRegistryBackend, type RegisteredClient } from './types';
type ForwardRequest = {
    clientId: string;
    type: string;
    data: unknown;
    timeoutMs?: number;
};
type ForwardResponse = {
    data?: unknown;
    error?: string;
    errorName?: string;
};
type KickClientRequest = {
    clientId: string;
};
type KickClientResponse = {
    kicked: boolean;
};
type UpdateMetaRequest = {
    clientId: string;
    metadata: unknown;
};
type UpdateMetaResponse = {
    updated: boolean;
};
type ForwardMessages = {
    forward: {
        request: ForwardRequest;
        response: ForwardResponse;
    };
    kickClient: {
        request: KickClientRequest;
        response: KickClientResponse;
    };
    updateMeta: {
        request: UpdateMetaRequest;
        response: UpdateMetaResponse;
    };
};
export interface MeshClientServiceOptions<TMeta> {
    key: string;
    meshOptions?: MeshServiceOptions;
    registryBackend?: MeshClientRegistryBackend<TMeta>;
    clientInvokeFn: (clientId: string, type: string, data: unknown, timeoutMs?: number) => Promise<unknown>;
    clientUpdateMetaFn?: (clientId: string, metadata: TMeta) => boolean;
}
export declare class MeshClientService<TMeta, TBroadcasts extends MeshBroadcastMap = {}> {
    /** @internal */
    readonly mesh: MeshService<ForwardMessages, TBroadcasts>;
    private logger;
    private registry;
    private backend;
    private clientInvokeFn;
    private clientUpdateMetaFn;
    private nodeCleanedUpCallbacks;
    private clientSupersededCallbacks;
    constructor(options: MeshClientServiceOptions<TMeta>);
    onNodeClientsOrphaned(cb: (nodeId: number, orphaned: RegisteredClient<TMeta>[]) => void | Promise<void>): void;
    onClientSuperseded(cb: (clientId: string) => void | Promise<void>): void;
    get instanceId(): number;
    get clientRegistry(): MeshClientRegistry<TMeta>;
    private running;
    start(): Promise<void>;
    stop(): Promise<void>;
    /**
     * Register a client on this node. Returns true if registered, false if
     * another node owns the client and `allowSupersede` is false (conflict).
     */
    registerClient(clientId: string, metadata: TMeta, allowSupersede?: boolean): Promise<boolean>;
    /**
     * Reserve ownership of a clientId without exposing it for lookup/invoke
     * until activation completes.
     */
    reserveClient(clientId: string, metadata: TMeta, allowSupersede?: boolean): Promise<boolean>;
    /**
     * Promote a same-node reservation to an active, discoverable client.
     */
    activateClient(clientId: string, metadata: TMeta): Promise<boolean>;
    unregisterClient(clientId: string): Promise<boolean>;
    updateClientMetadata(clientId: string, metadata: TMeta): Promise<boolean>;
    registerBroadcastHandler<K extends keyof TBroadcasts & string>(type: K, handler: (data: TBroadcasts[K], senderInstanceId: number) => void | Promise<void>): void;
    broadcast<K extends keyof TBroadcasts & string>(type: K, data: TBroadcasts[K], options?: MeshBroadcastOptions): Promise<void>;
    invoke(clientId: string, type: string, data: unknown, timeoutMs?: number): Promise<unknown>;
}
export {};
//# sourceMappingURL=mesh-client-service.d.ts.map