branch:
lobby-agent.ts
2644 bytesRaw
import { callable, getAgentByName } from "agents";
import { PlaygroundAgent as Agent } from "../../shared/playground-agent";
import type { RoomAgent } from "./room-agent";
export interface RoomInfo {
roomId: string;
memberCount: number;
createdAt: string;
}
export interface LobbyState {
rooms: Record<string, RoomInfo>;
}
export class LobbyAgent extends Agent<Env, LobbyState> {
initialState: LobbyState = {
rooms: {}
};
@callable({ description: "Create a new room" })
async createRoom(roomId: string): Promise<RoomInfo> {
// Initialize the room agent
const room = await getAgentByName<Env, RoomAgent>(
this.env.RoomAgent,
roomId
);
await room.initRoom(roomId);
// Track the room
const roomInfo: RoomInfo = {
roomId,
memberCount: 0,
createdAt: new Date().toISOString()
};
this.setState({
rooms: {
...this.state.rooms,
[roomId]: roomInfo
}
});
// Broadcast room list update
this.broadcast(
JSON.stringify({
type: "room_created",
room: roomInfo
})
);
return roomInfo;
}
@callable({ description: "List all rooms" })
listRooms(): RoomInfo[] {
return Object.values(this.state.rooms);
}
@callable({ description: "Get a specific room's info" })
getRoom(roomId: string): RoomInfo | null {
return this.state.rooms[roomId] || null;
}
// Called by RoomAgent when member count changes (DO RPC, not @callable for external clients)
updateRoomCount(roomId: string, memberCount: number): void {
if (this.state.rooms[roomId]) {
const updatedRoom = {
...this.state.rooms[roomId],
memberCount
};
this.setState({
rooms: {
...this.state.rooms,
[roomId]: updatedRoom
}
});
// Broadcast room update
this.broadcast(
JSON.stringify({
type: "room_updated",
room: updatedRoom
})
);
}
}
@callable({ description: "Delete a room" })
deleteRoom(roomId: string): boolean {
if (this.state.rooms[roomId]) {
const { [roomId]: _, ...remainingRooms } = this.state.rooms;
this.setState({ rooms: remainingRooms });
// Broadcast room deletion
this.broadcast(
JSON.stringify({
type: "room_deleted",
roomId
})
);
return true;
}
return false;
}
@callable({ description: "Get total users across all rooms" })
getTotalUsers(): number {
return Object.values(this.state.rooms).reduce(
(sum, room) => sum + room.memberCount,
0
);
}
}