import { Disposable } from "../interfaces/lifecycle.d.ts"; import { LibraryEventPayloadMap } from "../events/payloads.d.ts"; import { WildcardPattern } from "../events/types.d.ts"; import { LoggingUtility } from "../utils/logger.d.ts"; /** * A typed game event with compile-time payload checking. * * @template T - The event type string (e.g., 'input:changed') * @template TPayloadMap - The payload map to resolve types from */ export interface GameEvent = Record> { /** The string identifier/category of the event (e.g. "input:keydown"). */ type: T; /** The optional ID of whoever sent this event. */ senderID?: string; /** The optional ID of who should receive this event. */ targetID?: string; /** The payload, typed based on the payload map. */ payload: T extends keyof TPayloadMap ? TPayloadMap[T] : unknown; } /** * A callback function that receives a {@link GameEvent} with a given payload type. * * @template T - The event type string * @template TPayloadMap - The payload map to resolve types from */ export type GameEventCallback = Record> = (event: GameEvent) => void | Promise; /** * An unsubscribe function, returned by any subscribe method. */ export type Unsubscribe = () => void; /** * Callback for wildcard/pattern subscriptions. * Payload is unknown since multiple event types may match. */ export type WildcardEventCallback = (event: GameEvent>) => void | Promise; /** * A high-performance, type-safe event bus that supports exact or pattern-based subscriptions. * * The generic parameter `TPayloadMap` maps event type strings to their payload types, * enabling compile-time checking of event/payload combinations. * * @template TPayloadMap - Map of event type strings to their payload types. * Defaults to LibraryEventPayloadMap for internal library usage. * * @example * // Using library events (default) * const bus = new GameEventBus(); * bus.publish({ type: 'level:progress', payload: { levelName: 'Level1', progress: 50 } }); * * @example * // User-defined events with full type safety * interface MyEvents { * 'game:score-updated': { score: number; player: string }; * 'game:paused': { reason: string }; * [key: string]: unknown; // Allow other events * } * * const bus = new GameEventBus(); * bus.publish({ type: 'game:score-updated', payload: { score: 100, player: 'alice' } }); * * @example * // Merging user events with library events * const bus = new GameEventBus(); */ export declare class GameEventBus = LibraryEventPayloadMap> implements Disposable { /** * For exact event-type matches: * - Key = event type string (e.g. "input:keydown") * - Value = set of subscriptions for that exact type */ private directMap; /** * For pattern-based (wildcard or RegExp) subscriptions. */ private patternSubs; /** * Logger instance */ private _log; /** * Creates a new GameEventBus instance * * @param logger */ constructor(logger?: LoggingUtility); /** * Subscribe with automatic detection: * - If `eventTypeOrPattern` is a `RegExp` or a string containing `*`, treat it as a pattern subscription. * - Otherwise, treat it as an exact subscription. * * @template T - The event type string (must be a key in TPayloadMap for type safety) * @param eventTypeOrPattern - Exact event type string, wildcard pattern, or RegExp * @param callback * @returns A function that removes this subscription when called */ subscribe(eventTypeOrPattern: T | WildcardPattern | RegExp, callback: GameEventCallback): Unsubscribe; /** * Subscribes to an exact event type (e.g. "input:keydown"). * * @template T - The event type string (must be a key in TPayloadMap for type safety) * @param eventType * @param callback * @returns A function that removes this subscription when called */ subscribeExact(eventType: T, callback: GameEventCallback): Unsubscribe; /** * Subscribes with either: * - a wildcard string (contains `*`) that gets converted to a RegExp * - a RegExp directly * * Note: Payload typing is not available for wildcards since multiple event types may match. * * @param patternOrRegExp - Wildcard string (e.g. `"input:*"`) or a RegExp * @param callback * @returns A function that removes this subscription when called */ subscribePattern(patternOrRegExp: WildcardPattern | RegExp, callback: WildcardEventCallback): Unsubscribe; /** * Publishes an event, invoking all matching callbacks. * * **Async Execution Model:** * Callbacks are invoked asynchronously via the microtask queue using `Promise.resolve().then()`. * This means `publish()` returns immediately, before any callbacks execute. This design: * - Prevents stack overflow from recursive event publishing * - Allows multiple events to be queued before processing * - Is ideal for fire-and-forget events (notifications, state changes) * * **Not suitable for request-response patterns.** If you need to wait for a callback's * result, consider using a different communication mechanism. * * @template T - The event type string (must be a key in TPayloadMap for type safety) * @param event */ publish(event: GameEvent): void; /** * Tears down the event bus and clears all subscriptions. * After calling this method, no events will be delivered. */ $teardown(): Promise; }