feat(events,session): add React-friendly subscribe APIs and snapshot getters

Adds backwards-compatible primitives needed to consume the renderer from
React 19 hooks (useSyncExternalStore, use(), TanStack Query) without
re-architecting the event bus.

- EventDispatcher.subscribe(type, cb): () => void — unsubscriber-returning
  wrapper matching the useSyncExternalStore subscribe signature.
- CommunicationManager.subscribeMessage(eventCtor, handler): () => void —
  packet-stream equivalent.
- SessionDataManager.getUserDataSnapshot() and
  RoomSessionManager.getActiveRoomSessionSnapshot() — referentially-stable
  read-only views invalidated through new SESSION_DATA_UPDATED and
  ROOM_SESSION_UPDATED events.

All additive; existing addEventListener/removeEventListener / IRoomSession
APIs are unchanged. Bumps renderer to 2.1.0.
This commit is contained in:
simoleo89
2026-05-10 19:16:32 +02:00
parent 98b03aa0be
commit 87cf47847c
13 changed files with 193 additions and 5 deletions
@@ -7,4 +7,5 @@ export interface IEventDispatcher
removeEventListener(type: string, callback: Function): void;
removeAllListeners(): void;
dispatchEvent<T extends INitroEvent>(event: T): boolean;
subscribe<T extends INitroEvent>(type: string | string[], callback: (event: T) => void): () => void;
}
@@ -6,5 +6,6 @@ export interface ICommunicationManager
init(): Promise<void>;
registerMessageEvent(event: IMessageEvent): IMessageEvent;
removeMessageEvent(event: IMessageEvent): void;
subscribeMessage<T extends IMessageEvent>(eventCtor: new (callback: (event: T) => void) => T, handler: (event: T) => void): () => void;
connection: IConnection;
}
@@ -1,4 +1,5 @@
import { IRoomSession } from './IRoomSession';
import { IRoomSessionSnapshot } from './IRoomSessionSnapshot';
export interface IRoomSessionManager
{
@@ -8,5 +9,6 @@ export interface IRoomSessionManager
startSession(session: IRoomSession): boolean;
removeSession(id: number, openLandingView?: boolean): void;
tryRestoreSession(): boolean;
getActiveRoomSessionSnapshot(): Readonly<IRoomSessionSnapshot> | null;
viewerSession: IRoomSession;
}
@@ -0,0 +1,18 @@
import { IRoomSession } from './IRoomSession';
export interface IRoomSessionSnapshot
{
roomId: number;
state: string;
isRoomOwner: boolean;
isSpectator: boolean;
isDecorating: boolean;
isGuildRoom: boolean;
isPrivateRoom: boolean;
controllerLevel: number;
doorMode: number;
tradeMode: number;
allowPets: boolean;
groupId: number;
session: IRoomSession;
}
@@ -3,6 +3,7 @@ import { IFurnitureData } from './IFurnitureData';
import { IGroupInformationManager } from './IGroupInformationManager';
import { IIgnoredUsersManager } from './IIgnoredUsersManager';
import { IProductData } from './IProductData';
import { IUserDataSnapshot } from './IUserDataSnapshot';
export interface ISessionDataManager
{
@@ -53,4 +54,5 @@ export interface ISessionDataManager
isCameraFollowDisabled: boolean;
uiFlags: number;
tags: string[];
getUserDataSnapshot(): Readonly<IUserDataSnapshot>;
}
@@ -0,0 +1,22 @@
export interface IUserDataSnapshot
{
userId: number;
userName: string;
figure: string;
gender: string;
realName: string;
respectsReceived: number;
respectsLeft: number;
respectsPetLeft: number;
canChangeName: boolean;
clubLevel: number;
securityLevel: number;
isAmbassador: boolean;
isEmailVerified: boolean;
isNoob: boolean;
isAuthenticHabbo: boolean;
isSystemOpen: boolean;
isSystemShutdown: boolean;
uiFlags: number;
tags: ReadonlyArray<string>;
}
+2
View File
@@ -18,6 +18,8 @@ export * from './IRoomSessionManager';
export * from './IRoomUserData';
export * from './ISessionDataManager';
export * from './IUserDataManager';
export * from './IUserDataSnapshot';
export * from './IRoomSessionSnapshot';
export * from './PetBreedingResultData';
export * from './PetCustomPart';
export * from './PetFigureData';