import { Signal, WritableSignal, ComponentFunction } from 'canvasengine'; import { Subscription } from 'rxjs'; import { RpgContext } from '@rpgjs/common'; export type GuiRenderer = "canvas" | "vue"; export type GuiComponent = ComponentFunction | object; export interface GuiRegistration { name?: string; id?: string; component: TComponent; /** * Renderer responsible for this component. CanvasEngine is the v5 default. * `@rpgjs/vue` registers the official DOM overlay renderer. */ renderer?: GuiRenderer; display?: boolean; data?: TData; /** * Auto display the GUI when added to the system * @default false */ autoDisplay?: boolean; /** * Function that returns an array of Signal dependencies * The GUI will only display when all dependencies are resolved (!= undefined) * @returns Array of Signal dependencies */ dependencies?: () => Signal[]; /** * Attach the GUI to sprites instead of displaying globally * When true, the GUI will be rendered in character.ce for each sprite * @default false */ attachToSprite?: boolean; /** * Vue v4 compatibility flag. Prefer attachToSprite in v5 projects. */ rpgAttachToSprite?: boolean; } export type GuiEntry = GuiRegistration | GuiComponent; export interface GuiInstance { name: string; component: TComponent; renderer: GuiRenderer; display: WritableSignal; data: WritableSignal; openId?: string; autoDisplay: boolean; dependencies?: Signal[]; subscription?: Subscription; attachToSprite?: boolean; /** * Unique key of this registration, used to keep rendered GUIs mounted when * other GUIs are added. Replacing a GUI with the same name gets a new key. */ renderKey?: number; } export type GuiRenderState = { name: string; component: TComponent; renderer: GuiRenderer; display: boolean; data: TData; openId?: string; attachToSprite: boolean; }; interface GuiAction { guiId: string; name: string; data: any; clientActionId: string; } type OptimisticReducer = (data: any, action: GuiAction) => any; export declare class RpgGui { private context; private webSocket; gui: import('canvasengine').WritableObjectSignal>>; extraGuis: GuiInstance[]; private vueGuiInstance; private optimisticReducers; private pendingActions; /** * Signal tracking which player IDs should display attached GUIs * Key: player ID, Value: boolean (true = show, false = hide) */ attachedGuiDisplayState: import('canvasengine').WritableObjectSignal>; constructor(context: RpgContext); _initialize(): Promise; /** * Set the VueGui instance reference for Vue component management * This is called by VueGui when it's initialized * * @param vueGuiInstance - The VueGui instance */ _setVueGuiInstance(vueGuiInstance: any): void; /** * Notify VueGui about GUI state changes * This synchronizes the Vue component display state * * @param guiId - The GUI component ID * @param display - Display state * @param data - Component data */ private _notifyVueGui; /** * Initialize Vue components in the VueGui instance * This should be called after VueGui is mounted */ _initializeVueComponents(): void; guiInteraction(guiId: string, name: string, data: any): void; guiClose(guiId: string, data?: any, guiOpenId?: unknown): void; /** * Add a GUI component to the system * * By default, only CanvasEngine components (.ce files) are accepted. * Vue components should be handled by the @rpgjs/vue package. * * @param gui - GUI configuration options * @param gui.name - Name or ID of the GUI component * @param gui.id - Alternative ID if name is not provided * @param gui.component - The component to render (must be a CanvasEngine component) * @param gui.display - Initial display state (default: false) * @param gui.data - Initial data for the component * @param gui.autoDisplay - Auto display when added (default: false) * @param gui.dependencies - Function returning Signal dependencies * @param gui.attachToSprite - Attach GUI to sprites instead of global display (default: false) * * @example * ```ts * gui.add({ * name: 'inventory', * component: InventoryComponent, // Must be a .ce component * autoDisplay: true, * dependencies: () => [playerSignal, inventorySignal] * }); * * // Attach to sprites * gui.add({ * name: 'tooltip', * component: TooltipComponent, * attachToSprite: true * }); * ``` */ add(gui: GuiEntry): void; registerOptimisticReducer(guiId: string, reducer: OptimisticReducer): void; /** * Get all attached GUI components (attachToSprite: true) * * Returns all GUI instances that are configured to be attached to sprites. * These GUIs should be rendered in character.ce instead of canvas.ce. * * @returns Array of GUI instances with attachToSprite: true * * @example * ```ts * const attachedGuis = gui.getAttachedGuis(); * // Use in character.ce to render tooltips * ``` */ getAttachedGuis(): GuiInstance[]; getVueGuis(): GuiInstance[]; getAttachedVueGuis(): GuiInstance[]; /** * Check if a player should display attached GUIs * * @param playerId - The player ID to check * @returns true if attached GUIs should be displayed for this player */ shouldDisplayAttachedGui(playerId: string): boolean; get(id: string): GuiInstance | undefined; exists(id: string): boolean; getAll(): Record; /** * Display a GUI component * * Displays the GUI immediately if no dependencies are configured, * or waits for all dependencies to be resolved if dependencies are present. * Automatically manages subscriptions to prevent memory leaks. * Works with both CanvasEngine components and Vue components. * * @param id - The GUI component ID * @param data - Data to pass to the component * @param dependencies - Optional runtime dependencies (overrides config dependencies) * * @example * ```ts * // Display immediately * gui.display('inventory', { items: [] }); * * // Display with runtime dependencies * gui.display('shop', { shopId: 1 }, [playerSignal, shopSignal]); * ``` */ display(id: string, data?: unknown, dependencies?: Signal[], openId?: string): void; isDisplaying(id: string): boolean; /** * Handle Vue component display logic * * @param id - GUI component ID * @param data - Component data * @param dependencies - Runtime dependencies * @param guiInstance - GUI instance */ private _handleVueComponentDisplay; /** * Hide a GUI component * * Hides the GUI and cleans up any active subscriptions. * Works with both CanvasEngine components and Vue components. * * @param id - The GUI component ID * * @example * ```ts * gui.hide('inventory'); * ``` */ hide(id: string): void; private isVueComponent; private isVueComponentInstance; private removeCanvasGui; private removeVueGui; private resolveRegistration; private resolveComponentName; private resolveLegacyRenderer; private resolveAttachToSprite; private toGuiState; private clearPendingActions; private applyReducers; private applyOptimisticAction; private applyServerUpdate; } export {};