/** * RealtimeRoom — presence + broadcast over a {@link RealtimeTransport}. * * const room = RealtimeRoom.join({ * transport: new BroadcastChannelTransport({ id, channel: 'demo' }), * initialPresence: { name: 'Ada', color: '#6d5bfa' }, * }); * * room.onPresence((peers) => renderAvatars(peers)); * room.setPresence({ cursor: { x, y } }); * room.on('chat', (e) => appendMessage(e.payload)); * room.broadcast('chat', 'message', { text: 'hi' }); * * Presence is heartbeat-based: peers re-announce on an interval and are pruned * after a timeout. Transports with explicit teardown (MemoryHub) also emit an * immediate `bye` on {@link RealtimeRoom.leave}. */ import { Signal } from '../client/reactive.js'; import type { BroadcastEvent, PresencePeer, PresenceState, RealtimeMessage, RealtimeTransport } from './types.js'; export interface RealtimeRoomOptions

{ transport: RealtimeTransport; /** Initial presence for the local peer. */ initialPresence?: P; /** Heartbeat interval (ms). Default 2000. Set 0 to disable timers. */ heartbeatMs?: number; /** Peer expiry after no heartbeat (ms). Default 6000. */ timeoutMs?: number; /** Injectable clock for tests. Default `Date.now`. */ now?: () => number; } type BroadcastHandler = (event: BroadcastEvent) => void; export declare class RealtimeRoom

{ readonly id: string; private transport; private myState; private peers; /** Sender timestamps from presence messages (not local lastSeen). */ private presenceTsByPeer; private channelHandlers; private _presence; private now; private heartbeatMs; private timeoutMs; private heartbeatTimer?; private unsubscribe; private closed; private pendingReplay; /** Ids of broadcasts already delivered — keeps replay idempotent (G-Set). */ private seenMsgIds; private constructor(); /** Join a room and announce presence. */ static join

(opts: RealtimeRoomOptions

): RealtimeRoom

; /** The local peer id. */ get selfId(): string; /** Current local presence state. */ getSelfState(): P; /** Merge a partial update into local presence and broadcast it. */ setPresence(partial: Partial

): void; /** Replace local presence wholesale and broadcast it. */ replacePresence(state: P): void; /** All peers including self (self first). */ getPresence(): PresencePeer

[]; /** Peers excluding self. */ getOthers(): PresencePeer

[]; /** Subscribe to presence changes. Called immediately with current peers. */ onPresence(cb: (peers: PresencePeer

[]) => void): () => void; /** Reactive presence signal (for framework adapters). */ get presenceSignal(): Signal[]>; /** * Fire-and-forget broadcast to all other peers on a channel. Returns the * stable message id assigned to this broadcast — persist it alongside an * optimistic local render so an echoed copy (relay replay, reconnect) is * deduplicated by id rather than re-rendered. */ broadcast(channel: string, event: string, payload: unknown): string; private newMsgId; /** Subscribe to broadcasts on a channel. Returns an unsubscribe fn. */ on(channel: string, handler: BroadcastHandler): () => void; /** * Apply a relay replay batch (chat history, text snapshot, presence). * Used when reconnecting to a hub with {@link RelayPersistence}. */ replay(messages: RealtimeMessage[]): void; /** Announce departure and tear down. */ leave(): void; private handle; private flushPendingReplay; private hasActiveSubscribers; private integrateRemote; private upsertPeer; private announceHello; private announcePresence; private startHeartbeat; private pruneExpired; private recomputePresence; } export {}; //# sourceMappingURL=room.d.ts.map