import type { Message } from "@slackwsh/contracts";
import { type PersistedMention } from "../invariants";
import { Clock, Transport, type FaultConfig, type Rng } from "./sim";
export declare const SOCKET_TTL_MS = 60000;
export declare const SWEEP_INTERVAL_MS = 30000;
export interface SimUser {
    id: number;
    username: string;
}
export declare class SimServer {
    private readonly clock;
    private readonly transport;
    private readonly rng;
    private readonly faults;
    readonly workspaceId = 1;
    readonly channelId = 1;
    lastSeq: number;
    private nextMessageId;
    readonly messages: Map<number, {
        type: "text" | "system";
        id: number;
        createdAt: string;
        workspaceId: number;
        channelId: number;
        parentId: number | null;
        authorId: number;
        text: string;
        seq: number;
        clientMsgId: string;
        blocks: {
            v: 1;
            doc: Record<string, unknown>;
            forwardedMessage?: {
                createdAt: string;
                messageId: number;
                channelId: number;
                parentId: number | null;
                channelName: string | null;
                channelType: "public" | "private" | "dm" | "group_dm";
                authorId: number;
                authorName: string;
                authorAvatarUrl: string | null;
                text: string;
                attachmentNames: string[];
            } | undefined;
        };
        revision: number;
        isBroadcast: boolean;
        threadReplyCount: number;
        threadLastReplyAt: string | null;
        editedAt: string | null;
        deletedAt: string | null;
        reactions?: {
            emoji: string;
            count: number;
            reactedByMe: boolean;
        }[] | undefined;
    }>;
    readonly byClientMsg: Map<string, number>;
    readonly mentions: PersistedMention[];
    readonly members: Map<number, SimUser>;
    readonly lastReadSeq: Map<number, number>;
    readonly lastReadReplySeq: Map<string, number>;
    readonly mentionCount: Map<number, number>;
    readonly reactions: Map<string, {
        messageId: number;
        userId: number;
        emoji: string;
    }>;
    readonly threadFollowers: Map<number, Set<number>>;
    /** presence:{userId} socket set + liveness tokens. */
    private readonly sockets;
    private readonly userSockets;
    readonly displayedPresence: Map<number, "active" | "offline">;
    constructor(users: readonly SimUser[], clock: Clock, transport: Transport, rng: Rng, faults: FaultConfig);
    memberIds(): number[];
    allMessages(): Message[];
    connectSocket(userId: number, socketId: string): {
        becameOnline: boolean;
    };
    heartbeat(socketId: string): void;
    disconnectSocket(userId: number, socketId: string): {
        becameOffline: boolean;
    };
    /** Ungraceful death: socket vanishes without a disconnect handler. */
    dropSocketUngraceful(socketId: string): void;
    sweep(): void;
    liveSocketCount(userId: number): number;
    private publishPresence;
    send(input: {
        userId: number;
        clientMsgId: string;
        text: string;
        parentId?: number | null;
        isBroadcast?: boolean;
    }): Message;
    private persistMentions;
    edit(userId: number, messageId: number, text: string): Message;
    delete(messageId: number): void;
    react(userId: number, messageId: number, emoji: string): void;
    private syncReactionSummaries;
    ackRead(userId: number, seq: number): void;
    markUnread(userId: number, seq: number): void;
    ackThreadRead(userId: number, rootId: number, seq: number): void;
    scrollback(opts: {
        afterSeq?: number;
        beforeSeq?: number;
        limit: number;
    }): Message[];
    wire(message: Message, viewerId?: number): Message;
}
//# sourceMappingURL=server.d.ts.map