@teneo-protocol/sdk 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish-npm.yml +8 -6
- package/CHANGELOG.md +265 -0
- package/README.md +406 -53
- package/dist/core/websocket-client.d.ts +12 -0
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +22 -2
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +70 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +904 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js +51 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +65 -5
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +46 -4
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +5 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +23 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +877 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js +38 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +886 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js +51 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +178 -89
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js +92 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/types.d.ts +2 -0
- package/dist/handlers/message-handlers/types.d.ts.map +1 -1
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +222 -0
- package/dist/managers/agent-room-manager.d.ts.map +1 -0
- package/dist/managers/agent-room-manager.js +508 -0
- package/dist/managers/agent-room-manager.js.map +1 -0
- package/dist/managers/index.d.ts +2 -0
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js +5 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/room-management-manager.d.ts +213 -0
- package/dist/managers/room-management-manager.d.ts.map +1 -0
- package/dist/managers/room-management-manager.js +440 -0
- package/dist/managers/room-management-manager.js.map +1 -0
- package/dist/managers/room-manager.d.ts +4 -4
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/teneo-sdk.d.ts +333 -13
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +468 -1
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +63 -54
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +8 -4
- package/dist/types/config.js.map +1 -1
- package/dist/types/error-codes.d.ts +2 -0
- package/dist/types/error-codes.d.ts.map +1 -1
- package/dist/types/error-codes.js +3 -0
- package/dist/types/error-codes.js.map +1 -1
- package/dist/types/events.d.ts +132 -68
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +27 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +11396 -2559
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +294 -27
- package/dist/types/messages.js.map +1 -1
- package/examples/.env.example +1 -1
- package/examples/agent-room-management-example.ts +334 -0
- package/examples/claude-agent-x-follower/.env.example +2 -2
- package/examples/claude-agent-x-follower/QUICKSTART.md +1 -1
- package/examples/claude-agent-x-follower/README.md +1 -1
- package/examples/n8n-teneo/.env.example +2 -2
- package/examples/n8n-teneo/README.md +1 -1
- package/examples/openai-teneo/.env.example +2 -2
- package/examples/openai-teneo/README.md +1 -1
- package/examples/production-dashboard/.env.example +2 -2
- package/examples/production-dashboard/README.md +89 -12
- package/examples/production-dashboard/public/dashboard.html +1173 -601
- package/examples/production-dashboard/server.ts +347 -5
- package/examples/room-management-example.ts +285 -0
- package/examples/usage/.env.example +1 -1
- package/examples/usage/01-connect.ts +1 -1
- package/examples/usage/02-list-agents.ts +1 -1
- package/examples/usage/03-pick-agent.ts +1 -1
- package/examples/usage/04-find-by-capability.ts +1 -1
- package/examples/usage/05-webhook-example.ts +1 -1
- package/examples/usage/06-simple-api-server.ts +1 -1
- package/examples/usage/07-event-listener.ts +1 -1
- package/examples/usage/README.md +1 -1
- package/package.json +9 -1
- package/src/core/websocket-client.ts +26 -2
- package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +83 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +58 -0
- package/src/handlers/message-handlers/auth-message-handler.ts +73 -5
- package/src/handlers/message-handlers/auth-success-handler.ts +58 -6
- package/src/handlers/message-handlers/index.ts +19 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
- package/src/handlers/message-handlers/list-room-agents-handler.ts +61 -0
- package/src/handlers/message-handlers/room-operation-response-handler.ts +105 -0
- package/src/handlers/message-handlers/types.ts +6 -0
- package/src/managers/agent-room-manager.ts +609 -0
- package/src/managers/index.ts +2 -0
- package/src/managers/room-management-manager.ts +523 -0
- package/src/managers/room-manager.ts +4 -5
- package/src/teneo-sdk.ts +505 -4
- package/src/types/config.ts +10 -5
- package/src/types/error-codes.ts +4 -0
- package/src/types/events.ts +24 -0
- package/src/types/index.ts +55 -0
- package/src/types/messages.ts +374 -41
- package/tests/integration/room-management.test.ts +514 -0
- package/tests/integration/websocket.test.ts +1 -1
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +394 -0
- package/tests/unit/handlers/agent-status-update-handler.test.ts +407 -0
- package/tests/unit/handlers/auth-success-handler-rooms.test.ts +699 -0
- package/tests/unit/handlers/list-available-agents-handler.test.ts +256 -0
- package/tests/unit/handlers/list-room-agents-handler.test.ts +294 -0
- package/tests/unit/handlers/room-operation-response-handler.test.ts +527 -0
- package/tests/unit/managers/agent-room-manager.test.ts +534 -0
- package/tests/unit/managers/room-management-manager.test.ts +438 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RoomManagementManager - Manages room CRUD operations (v2.0.0)
|
|
3
|
+
* Handles creating, updating, and deleting private rooms
|
|
4
|
+
* Tracks owned vs shared rooms with local caching
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter } from "eventemitter3";
|
|
8
|
+
import { WebSocketClient } from "../core/websocket-client";
|
|
9
|
+
import { RoomInfo, Logger } from "../types";
|
|
10
|
+
import { SDKEvents, SDKError } from "../types/events";
|
|
11
|
+
import { ErrorCode } from "../types/error-codes";
|
|
12
|
+
|
|
13
|
+
export interface CreateRoomOptions {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UpdateRoomOptions {
|
|
19
|
+
name?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class RoomManagementManager extends EventEmitter<SDKEvents> {
|
|
24
|
+
private readonly wsClient: WebSocketClient;
|
|
25
|
+
private readonly logger: Logger;
|
|
26
|
+
|
|
27
|
+
// Room caches
|
|
28
|
+
private readonly ownedRooms = new Map<string, RoomInfo>(); // Rooms user owns
|
|
29
|
+
private readonly sharedRooms = new Map<string, RoomInfo>(); // Rooms user is member of
|
|
30
|
+
private maxPrivateRooms: number = 1; // Default limit
|
|
31
|
+
|
|
32
|
+
constructor(wsClient: WebSocketClient, logger: Logger) {
|
|
33
|
+
super();
|
|
34
|
+
this.wsClient = wsClient;
|
|
35
|
+
this.logger = logger;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// ROOM CRUD OPERATIONS
|
|
40
|
+
// ============================================================================
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new private room.
|
|
44
|
+
* Checks room limit before creating.
|
|
45
|
+
*
|
|
46
|
+
* @param options - Room creation options
|
|
47
|
+
* @returns Promise that resolves when room is created
|
|
48
|
+
* @throws {SDKError} If not connected, over limit, or validation fails
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const room = await sdk.rooms.createRoom({
|
|
53
|
+
* name: 'My Private Room',
|
|
54
|
+
* description: 'A room for my project'
|
|
55
|
+
* });
|
|
56
|
+
* console.log(`Created room: ${room.id}`);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
public async createRoom(options: CreateRoomOptions): Promise<RoomInfo> {
|
|
60
|
+
if (!this.wsClient.isConnected) {
|
|
61
|
+
throw new SDKError("Not connected to Teneo network", ErrorCode.NOT_CONNECTED);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Validate inputs
|
|
65
|
+
this.validateRoomName(options.name);
|
|
66
|
+
if (options.description !== undefined) {
|
|
67
|
+
this.validateRoomDescription(options.description);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check room limit
|
|
71
|
+
if (!this.canCreateRoom()) {
|
|
72
|
+
throw new SDKError(
|
|
73
|
+
`Room limit reached. Maximum ${this.maxPrivateRooms} private rooms allowed.`,
|
|
74
|
+
ErrorCode.VALIDATION_ERROR
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.logger.debug("RoomManagementManager: Creating room", options);
|
|
79
|
+
|
|
80
|
+
// Send create_room message
|
|
81
|
+
const message = {
|
|
82
|
+
type: "create_room" as const,
|
|
83
|
+
data: {
|
|
84
|
+
name: options.name,
|
|
85
|
+
description: options.description
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Return promise that will be resolved by the response handler
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const timeout = setTimeout(() => {
|
|
92
|
+
cleanup();
|
|
93
|
+
reject(new SDKError("Room creation timeout", ErrorCode.TIMEOUT));
|
|
94
|
+
}, 30000);
|
|
95
|
+
|
|
96
|
+
const onSuccess = (room: RoomInfo) => {
|
|
97
|
+
cleanup();
|
|
98
|
+
resolve(room);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const onError = (error: Error) => {
|
|
102
|
+
cleanup();
|
|
103
|
+
reject(error);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const cleanup = () => {
|
|
107
|
+
clearTimeout(timeout);
|
|
108
|
+
this.off("room:created", onSuccess);
|
|
109
|
+
this.off("room:create_error", onError);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
this.once("room:created", onSuccess);
|
|
113
|
+
this.once("room:create_error", onError);
|
|
114
|
+
|
|
115
|
+
this.wsClient.sendMessage(message);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Updates an existing room's name and/or description.
|
|
121
|
+
* User must own the room to update it.
|
|
122
|
+
*
|
|
123
|
+
* @param roomId - ID of room to update
|
|
124
|
+
* @param updates - Fields to update
|
|
125
|
+
* @returns Promise that resolves when room is updated
|
|
126
|
+
* @throws {SDKError} If not connected, not owner, or validation fails
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* await sdk.rooms.updateRoom('room-123', {
|
|
131
|
+
* name: 'Updated Room Name',
|
|
132
|
+
* description: 'New description'
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
public async updateRoom(roomId: string, updates: UpdateRoomOptions): Promise<RoomInfo> {
|
|
137
|
+
if (!this.wsClient.isConnected) {
|
|
138
|
+
throw new SDKError("Not connected to Teneo network", ErrorCode.NOT_CONNECTED);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Verify user owns room
|
|
142
|
+
if (!this.ownedRooms.has(roomId)) {
|
|
143
|
+
throw new SDKError(
|
|
144
|
+
"Cannot update room: You don't own this room",
|
|
145
|
+
ErrorCode.PERMISSION_DENIED
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Validate at least one field is provided
|
|
150
|
+
if (updates.name === undefined && updates.description === undefined) {
|
|
151
|
+
throw new SDKError(
|
|
152
|
+
"At least one field (name or description) must be provided",
|
|
153
|
+
ErrorCode.VALIDATION_ERROR
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Validate inputs
|
|
158
|
+
if (updates.name !== undefined) {
|
|
159
|
+
this.validateRoomName(updates.name);
|
|
160
|
+
}
|
|
161
|
+
if (updates.description !== undefined) {
|
|
162
|
+
this.validateRoomDescription(updates.description);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.logger.debug("RoomManagementManager: Updating room", { roomId, updates });
|
|
166
|
+
|
|
167
|
+
// Send update_room message
|
|
168
|
+
const message = {
|
|
169
|
+
type: "update_room" as const,
|
|
170
|
+
data: {
|
|
171
|
+
room_id: roomId,
|
|
172
|
+
name: updates.name,
|
|
173
|
+
description: updates.description
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return new Promise((resolve, reject) => {
|
|
178
|
+
const timeout = setTimeout(() => {
|
|
179
|
+
cleanup();
|
|
180
|
+
reject(new SDKError("Room update timeout", ErrorCode.TIMEOUT));
|
|
181
|
+
}, 30000);
|
|
182
|
+
|
|
183
|
+
const onSuccess = (room: RoomInfo) => {
|
|
184
|
+
// Only resolve if it's the room we're updating
|
|
185
|
+
if (room.id === roomId) {
|
|
186
|
+
cleanup();
|
|
187
|
+
resolve(room);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const onError = (error: Error, responseRoomId?: string) => {
|
|
192
|
+
if (!responseRoomId || responseRoomId === roomId) {
|
|
193
|
+
cleanup();
|
|
194
|
+
reject(error);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const cleanup = () => {
|
|
199
|
+
clearTimeout(timeout);
|
|
200
|
+
this.off("room:updated", onSuccess);
|
|
201
|
+
this.off("room:update_error", onError);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
this.once("room:updated", onSuccess);
|
|
205
|
+
this.once("room:update_error", onError);
|
|
206
|
+
|
|
207
|
+
this.wsClient.sendMessage(message);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Deletes a room permanently.
|
|
213
|
+
* User must own the room to delete it.
|
|
214
|
+
*
|
|
215
|
+
* @param roomId - ID of room to delete
|
|
216
|
+
* @returns Promise that resolves when room is deleted
|
|
217
|
+
* @throws {SDKError} If not connected or not owner
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* await sdk.rooms.deleteRoom('room-123');
|
|
222
|
+
* console.log('Room deleted successfully');
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
public async deleteRoom(roomId: string): Promise<void> {
|
|
226
|
+
if (!this.wsClient.isConnected) {
|
|
227
|
+
throw new SDKError("Not connected to Teneo network", ErrorCode.NOT_CONNECTED);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Verify user owns room
|
|
231
|
+
if (!this.ownedRooms.has(roomId)) {
|
|
232
|
+
throw new SDKError(
|
|
233
|
+
"Cannot delete room: You don't own this room",
|
|
234
|
+
ErrorCode.PERMISSION_DENIED
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
this.logger.debug("RoomManagementManager: Deleting room", { roomId });
|
|
239
|
+
|
|
240
|
+
// Send delete_room message
|
|
241
|
+
const message = {
|
|
242
|
+
type: "delete_room" as const,
|
|
243
|
+
data: {
|
|
244
|
+
room_id: roomId
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
return new Promise((resolve, reject) => {
|
|
249
|
+
const timeout = setTimeout(() => {
|
|
250
|
+
cleanup();
|
|
251
|
+
reject(new SDKError("Room deletion timeout", ErrorCode.TIMEOUT));
|
|
252
|
+
}, 30000);
|
|
253
|
+
|
|
254
|
+
const onSuccess = (deletedRoomId: string) => {
|
|
255
|
+
if (deletedRoomId === roomId) {
|
|
256
|
+
cleanup();
|
|
257
|
+
resolve();
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const onError = (error: Error, responseRoomId?: string) => {
|
|
262
|
+
if (!responseRoomId || responseRoomId === roomId) {
|
|
263
|
+
cleanup();
|
|
264
|
+
reject(error);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const cleanup = () => {
|
|
269
|
+
clearTimeout(timeout);
|
|
270
|
+
this.off("room:deleted", onSuccess);
|
|
271
|
+
this.off("room:delete_error", onError);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
this.once("room:deleted", onSuccess);
|
|
275
|
+
this.once("room:delete_error", onError);
|
|
276
|
+
|
|
277
|
+
this.wsClient.sendMessage(message);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ============================================================================
|
|
282
|
+
// QUERY METHODS (Synchronous, from cache)
|
|
283
|
+
// ============================================================================
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Gets all rooms owned by the current user.
|
|
287
|
+
* Synchronous method that returns cached data.
|
|
288
|
+
*
|
|
289
|
+
* @returns Array of owned room info
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const myRooms = sdk.rooms.getOwnedRooms();
|
|
294
|
+
* console.log(`I own ${myRooms.length} rooms`);
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
public getOwnedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
|
|
298
|
+
return Array.from(this.ownedRooms.values()).map((room) => ({ ...room }));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Gets all rooms the user is a member of (but doesn't own).
|
|
303
|
+
* Synchronous method that returns cached data.
|
|
304
|
+
*
|
|
305
|
+
* @returns Array of shared room info
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```typescript
|
|
309
|
+
* const sharedRooms = sdk.rooms.getSharedRooms();
|
|
310
|
+
* console.log(`I'm a member of ${sharedRooms.length} shared rooms`);
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
public getSharedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
|
|
314
|
+
return Array.from(this.sharedRooms.values()).map((room) => ({ ...room }));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Gets all rooms the user has access to (both owned and shared).
|
|
319
|
+
* Convenience method that combines getOwnedRooms() and getSharedRooms().
|
|
320
|
+
* Synchronous method that returns cached data.
|
|
321
|
+
*
|
|
322
|
+
* @returns Array of all room info (owned + shared)
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```typescript
|
|
326
|
+
* const allRooms = sdk.getAllRooms();
|
|
327
|
+
* console.log(`I have access to ${allRooms.length} total rooms`);
|
|
328
|
+
*
|
|
329
|
+
* // Filter by ownership if needed
|
|
330
|
+
* const myRooms = allRooms.filter(r => r.is_owner);
|
|
331
|
+
* const sharedWithMe = allRooms.filter(r => !r.is_owner);
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
public getAllRooms(): ReadonlyArray<Readonly<RoomInfo>> {
|
|
335
|
+
return [...this.getOwnedRooms(), ...this.getSharedRooms()];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Gets a specific room by ID.
|
|
340
|
+
* Checks both owned and shared room caches.
|
|
341
|
+
*
|
|
342
|
+
* @param roomId - Room ID to look up
|
|
343
|
+
* @returns Room info if found, undefined otherwise
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const room = sdk.rooms.getRoomById('room-123');
|
|
348
|
+
* if (room) {
|
|
349
|
+
* console.log(`Room: ${room.name}`);
|
|
350
|
+
* }
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
public getRoomById(roomId: string): Readonly<RoomInfo> | undefined {
|
|
354
|
+
const owned = this.ownedRooms.get(roomId);
|
|
355
|
+
if (owned) return { ...owned };
|
|
356
|
+
|
|
357
|
+
const shared = this.sharedRooms.get(roomId);
|
|
358
|
+
if (shared) return { ...shared };
|
|
359
|
+
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Gets the maximum number of private rooms the user can create.
|
|
365
|
+
* Based on user's subscription/plan.
|
|
366
|
+
*
|
|
367
|
+
* @returns Maximum private room limit
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* const limit = sdk.rooms.getRoomLimit();
|
|
372
|
+
* console.log(`You can create up to ${limit} private rooms`);
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
public getRoomLimit(): number {
|
|
376
|
+
return this.maxPrivateRooms;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Checks if user can create another private room.
|
|
381
|
+
* Compares current owned room count against limit.
|
|
382
|
+
*
|
|
383
|
+
* @returns True if under limit, false otherwise
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* if (sdk.rooms.canCreateRoom()) {
|
|
388
|
+
* await sdk.rooms.createRoom({ name: 'New Room' });
|
|
389
|
+
* } else {
|
|
390
|
+
* console.log('Room limit reached!');
|
|
391
|
+
* }
|
|
392
|
+
* ```
|
|
393
|
+
*/
|
|
394
|
+
public canCreateRoom(): boolean {
|
|
395
|
+
return this.ownedRooms.size < this.maxPrivateRooms;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Gets the current count of owned private rooms.
|
|
400
|
+
*
|
|
401
|
+
* @returns Number of rooms user owns
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* const count = sdk.rooms.getOwnedRoomCount();
|
|
406
|
+
* const limit = sdk.rooms.getRoomLimit();
|
|
407
|
+
* console.log(`Using ${count}/${limit} room slots`);
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
public getOwnedRoomCount(): number {
|
|
411
|
+
return this.ownedRooms.size;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ============================================================================
|
|
415
|
+
// INTERNAL METHODS (Called by SDK internals)
|
|
416
|
+
// ============================================================================
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Sets the room limit from auth response.
|
|
420
|
+
* @internal
|
|
421
|
+
*/
|
|
422
|
+
public setRoomLimit(limit: number): void {
|
|
423
|
+
this.maxPrivateRooms = limit;
|
|
424
|
+
this.logger.debug("RoomManagementManager: Room limit set", { limit });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Initializes owned rooms cache from auth response.
|
|
429
|
+
* @internal
|
|
430
|
+
*/
|
|
431
|
+
public setOwnedRooms(rooms: RoomInfo[]): void {
|
|
432
|
+
this.ownedRooms.clear();
|
|
433
|
+
for (const room of rooms) {
|
|
434
|
+
this.ownedRooms.set(room.id, room);
|
|
435
|
+
}
|
|
436
|
+
this.logger.debug("RoomManagementManager: Owned rooms set", { count: rooms.length });
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Initializes shared rooms cache from auth response.
|
|
441
|
+
* @internal
|
|
442
|
+
*/
|
|
443
|
+
public setSharedRooms(rooms: RoomInfo[]): void {
|
|
444
|
+
this.sharedRooms.clear();
|
|
445
|
+
for (const room of rooms) {
|
|
446
|
+
this.sharedRooms.set(room.id, room);
|
|
447
|
+
}
|
|
448
|
+
this.logger.debug("RoomManagementManager: Shared rooms set", { count: rooms.length });
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Adds or updates a room in the appropriate cache.
|
|
453
|
+
* Determines owned vs shared based on is_owner flag.
|
|
454
|
+
* @internal
|
|
455
|
+
*/
|
|
456
|
+
public upsertRoom(room: RoomInfo): void {
|
|
457
|
+
if (room.is_owner) {
|
|
458
|
+
this.ownedRooms.set(room.id, room);
|
|
459
|
+
// Remove from shared if it was there
|
|
460
|
+
this.sharedRooms.delete(room.id);
|
|
461
|
+
this.logger.debug("RoomManagementManager: Upserted owned room", { roomId: room.id });
|
|
462
|
+
} else {
|
|
463
|
+
this.sharedRooms.set(room.id, room);
|
|
464
|
+
// Remove from owned if it was there
|
|
465
|
+
this.ownedRooms.delete(room.id);
|
|
466
|
+
this.logger.debug("RoomManagementManager: Upserted shared room", { roomId: room.id });
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Removes a room from cache.
|
|
472
|
+
* Checks both owned and shared caches.
|
|
473
|
+
* @internal
|
|
474
|
+
*/
|
|
475
|
+
public removeRoom(roomId: string): void {
|
|
476
|
+
const wasOwned = this.ownedRooms.delete(roomId);
|
|
477
|
+
const wasShared = this.sharedRooms.delete(roomId);
|
|
478
|
+
|
|
479
|
+
if (wasOwned || wasShared) {
|
|
480
|
+
this.logger.debug("RoomManagementManager: Removed room", {
|
|
481
|
+
roomId,
|
|
482
|
+
wasOwned,
|
|
483
|
+
wasShared
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Clears all caches. Called on disconnect.
|
|
490
|
+
* @internal
|
|
491
|
+
*/
|
|
492
|
+
public clearCaches(): void {
|
|
493
|
+
this.ownedRooms.clear();
|
|
494
|
+
this.sharedRooms.clear();
|
|
495
|
+
this.maxPrivateRooms = 1;
|
|
496
|
+
this.logger.debug("RoomManagementManager: Caches cleared");
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// ============================================================================
|
|
500
|
+
// VALIDATION
|
|
501
|
+
// ============================================================================
|
|
502
|
+
|
|
503
|
+
private validateRoomName(name: string): void {
|
|
504
|
+
if (!name || name.trim().length === 0) {
|
|
505
|
+
throw new SDKError("Room name cannot be empty", ErrorCode.VALIDATION_ERROR);
|
|
506
|
+
}
|
|
507
|
+
if (name.length > 100) {
|
|
508
|
+
throw new SDKError(
|
|
509
|
+
"Room name too long (max 100 characters)",
|
|
510
|
+
ErrorCode.VALIDATION_ERROR
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
private validateRoomDescription(description: string): void {
|
|
516
|
+
if (description.length > 500) {
|
|
517
|
+
throw new SDKError(
|
|
518
|
+
"Room description too long (max 500 characters)",
|
|
519
|
+
ErrorCode.VALIDATION_ERROR
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { EventEmitter } from "eventemitter3";
|
|
7
7
|
import { WebSocketClient } from "../core/websocket-client";
|
|
8
8
|
import {
|
|
9
|
-
Room,
|
|
10
9
|
createSubscribe,
|
|
11
10
|
createUnsubscribe,
|
|
12
11
|
createListRooms,
|
|
@@ -20,7 +19,7 @@ import { RoomIdSchema } from "../types/validation";
|
|
|
20
19
|
export class RoomManager extends EventEmitter<SDKEvents> {
|
|
21
20
|
private readonly wsClient: WebSocketClient;
|
|
22
21
|
private readonly logger: Logger;
|
|
23
|
-
private readonly rooms = new Map<string,
|
|
22
|
+
private readonly rooms = new Map<string, RoomInfo>();
|
|
24
23
|
private readonly subscribedRooms = new Set<string>();
|
|
25
24
|
|
|
26
25
|
constructor(wsClient: WebSocketClient, logger: Logger) {
|
|
@@ -141,7 +140,7 @@ export class RoomManager extends EventEmitter<SDKEvents> {
|
|
|
141
140
|
* rooms.forEach(room => console.log(`${room.id}: ${room.name}`));
|
|
142
141
|
* ```
|
|
143
142
|
*/
|
|
144
|
-
public getRooms(): ReadonlyArray<Readonly<
|
|
143
|
+
public getRooms(): ReadonlyArray<Readonly<RoomInfo>> {
|
|
145
144
|
return Array.from(this.rooms.values()).map((room) => ({ ...room }));
|
|
146
145
|
}
|
|
147
146
|
|
|
@@ -162,7 +161,7 @@ export class RoomManager extends EventEmitter<SDKEvents> {
|
|
|
162
161
|
* }
|
|
163
162
|
* ```
|
|
164
163
|
*/
|
|
165
|
-
public getRoom(roomId: string): Readonly<
|
|
164
|
+
public getRoom(roomId: string): Readonly<RoomInfo> | undefined {
|
|
166
165
|
const room = this.rooms.get(roomId);
|
|
167
166
|
return room ? { ...room } : undefined;
|
|
168
167
|
}
|
|
@@ -213,7 +212,7 @@ export class RoomManager extends EventEmitter<SDKEvents> {
|
|
|
213
212
|
* roomManager.updateRoomsFromAuth(authState.roomObjects);
|
|
214
213
|
* ```
|
|
215
214
|
*/
|
|
216
|
-
public updateRoomsFromAuth(rooms:
|
|
215
|
+
public updateRoomsFromAuth(rooms: RoomInfo[]): void {
|
|
217
216
|
this.logger.debug("RoomManager: Updating rooms from auth", { count: rooms.length });
|
|
218
217
|
|
|
219
218
|
for (const room of rooms) {
|