/** * Messaging stores — typed inboxes over the three message-shaped realtime * surfaces: channel messages ({@link ChannelInbox}), direct actor-to-actor * messages ({@link ActorInbox}), and app-defined client/server events * ({@link EventRouter}). Each keeps a queryable history and dispatches typed * callbacks, replacing the per-app chat rings and payload plumbing. */ import type { ChunkCoordinatesInput } from '../generated/graphql.js'; import { type StateCodec } from './codec.js'; import type { WorldSessionContext } from './session.js'; /** A decoded message in a {@link ChannelInbox} or {@link ActorInbox}. */ export interface InboxMessage { /** The channel id (channel messages) or the notification uuid (actor messages). */ channelId?: string; /** * The uuid on the wire. For channel messages this is the SENDER's actor * uuid; for single-actor messages the payload is opaque to the server, so * apps conventionally embed the sender identity in the payload itself. */ uuid: string; /** The decoded payload. */ payload: T; epochMillis: number; receivedAt: number; } /** Options for {@link attachChannelInbox}. */ export interface ChannelInboxConfig { /** Codec for message payloads. Defaults to UTF-8 text. */ codec?: StateCodec; /** Messages kept per channel (oldest dropped). Defaults to 100. */ capacity?: number; /** * The sender uuid stamped on outbound messages. Wired from the session's * local actor automatically; a random uuid otherwise. */ senderUuid?: string | (() => string | null); /** Clock override for tests. Defaults to `Date.now`. */ now?: () => number; } /** * The SDK-managed **channel inbox**: every `channelMessage` notification is * decoded and appended to a per-channel history ring (chronological, capped), * with typed send + subscribe. This is the inbound channel fan-out most * games never get around to writing. */ export declare class ChannelInbox { private readonly ctx; private readonly config; private readonly byChannel; private readonly listeners; private readonly codec; private readonly capacity; private readonly now; private readonly fallbackUuid; private decodeFailureCount; private sequence; constructor(ctx: WorldSessionContext, config?: ChannelInboxConfig); /** One channel's history, oldest first (capped at `capacity`). */ messages(channelId: string): Array>; /** Channel ids with recorded history. */ channels(): string[]; /** Payloads that failed to decode (foreign encodings). */ get decodeFailures(): number; /** * Subscribe to incoming messages — every channel, or one `channelId`. * @returns off. */ onMessage(handler: (message: InboxMessage) => void, channelId?: string): () => void; /** * Send a typed payload to a channel (requires membership with * `send_messages`; delivery is app-wide, not chunk-routed). */ send(channelId: string, payload: T): Promise; /** Drop history (one channel, or all). */ clear(channelId?: string): void; private ring; private senderUuid; private nextSequence; } /** Attach a {@link ChannelInbox}. Prefer the `channelInbox` config key. */ export declare function attachChannelInbox(ctx: WorldSessionContext, config?: ChannelInboxConfig): ChannelInbox; /** Options for {@link attachActorInbox}. */ export interface ActorInboxConfig { /** Codec for message payloads. Defaults to UTF-8 text. */ codec?: StateCodec; /** Messages kept (oldest dropped). Defaults to 100. */ capacity?: number; /** Clock override for tests. Defaults to `Date.now`. */ now?: () => number; } /** * The SDK-managed **direct-message inbox**: `singleActorMessage` * notifications decoded into a capped history with typed subscribe, plus a * typed `send` (the sender must know the target's current chunk — pair with * a {@link RemoteActorStore}, whose records carry it). */ export declare class ActorInbox { private readonly ctx; private readonly history; private readonly listeners; private readonly codec; private readonly capacity; private readonly now; private decodeFailureCount; private sequence; constructor(ctx: WorldSessionContext, config?: ActorInboxConfig); /** Received messages, oldest first (capped at `capacity`). */ messages(): Array>; /** Payloads that failed to decode. */ get decodeFailures(): number; /** Subscribe to incoming direct messages. @returns off. */ onMessage(listener: (message: InboxMessage) => void): () => void; /** * Send a typed payload to one actor (identified by uuid + its current * chunk). Fire-and-forget: `true` means accepted for sending. */ send(targetUuid: string, payload: T, targetChunk: ChunkCoordinatesInput): Promise; /** Drop the history. */ clear(): void; private nextSequence; } /** Attach an {@link ActorInbox}. Prefer the `actorInbox` config key. */ export declare function attachActorInbox(ctx: WorldSessionContext, config?: ActorInboxConfig): ActorInbox; /** A decoded client/server event delivered by the {@link EventRouter}. */ export interface TypedEvent { eventType: number; /** Whether another client or the server (model notification) emitted it. */ origin: 'client' | 'server'; /** The emitting actor/source uuid. */ uuid: string; value: T; chunk: ChunkCoordinatesInput; epochMillis: number; receivedAt: number; } /** Options for {@link attachEventRouter}. */ export interface EventRouterConfig { /** * The sender uuid stamped on outbound events. Wired from the session's * local actor automatically; a random uuid otherwise. */ senderUuid?: string | (() => string | null); /** Replication radius for outbound events (0-8). */ distance?: number; /** Clock override for tests. Defaults to `Date.now`. */ now?: () => number; } /** * The SDK-managed **event router**: register a codec + handler per * app-defined `eventType` (uint16) and receive typed client AND server * events; the latest decoded event per type stays queryable via * {@link lastEvent}. Send typed events with {@link send}. */ export declare class EventRouter { private readonly ctx; private readonly config; private readonly registrations; private readonly lastByType; private readonly now; private readonly fallbackUuid; private decodeFailureCount; private sequence; constructor(ctx: WorldSessionContext, config?: EventRouterConfig); /** * Register a typed handler for one `eventType`. Multiple handlers (even * with different codecs) may coexist per type. * @returns off. */ on(eventType: number, codec: StateCodec, handler: (event: TypedEvent) => void): () => void; /** The latest decoded event of one type (undefined before the first). */ lastEvent(eventType: number): TypedEvent | undefined; /** Events whose registered codec failed to decode. */ get decodeFailures(): number; /** * Send a typed app-defined event to a chunk (fanned out to nearby actors * as a `ClientEventNotification`). */ send(eventType: number, codec: StateCodec, value: T, chunk: ChunkCoordinatesInput): Promise; private senderUuid; private nextSequence; } /** Attach an {@link EventRouter}. Prefer the `events` config key. */ export declare function attachEventRouter(ctx: WorldSessionContext, config?: EventRouterConfig): EventRouter; //# sourceMappingURL=inbox.d.ts.map