@principal-ai/control-tower-core 0.2.0 → 0.2.2
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/dist/abstractions/ConnectedRoomManager.d.ts +22 -0
- package/dist/abstractions/ConnectedRoomManager.d.ts.map +1 -0
- package/dist/abstractions/ConnectedRoomManager.js +56 -0
- package/dist/abstractions/index.d.ts +1 -0
- package/dist/abstractions/index.d.ts.map +1 -1
- package/dist/abstractions/index.js +3 -1
- package/dist/generated/client-connection-auth.types.d.ts +312 -0
- package/dist/generated/client-connection-auth.types.d.ts.map +1 -0
- package/dist/generated/client-connection-auth.types.js +11 -0
- package/dist/generated/control-tower-execution.types.d.ts +445 -0
- package/dist/generated/control-tower-execution.types.d.ts.map +1 -0
- package/dist/generated/control-tower-execution.types.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +8 -7
- package/dist/index.mjs +180 -99
- package/dist/index.mjs.map +8 -7
- package/dist/server/BaseServer.d.ts +30 -2
- package/dist/server/BaseServer.d.ts.map +1 -1
- package/dist/server/BaseServer.js +77 -8
- package/dist/server/ServerBuilder.d.ts.map +1 -1
- package/dist/server/ServerBuilder.js +11 -0
- package/dist/telemetry/EventValidationIntegration.d.ts +135 -0
- package/dist/telemetry/EventValidationIntegration.d.ts.map +1 -0
- package/dist/telemetry/EventValidationIntegration.js +253 -0
- package/dist/telemetry/EventValidationIntegration.test.d.ts +7 -0
- package/dist/telemetry/EventValidationIntegration.test.d.ts.map +1 -0
- package/dist/telemetry/EventValidationIntegration.test.js +322 -0
- package/dist/telemetry/TelemetryCapture.d.ts +268 -0
- package/dist/telemetry/TelemetryCapture.d.ts.map +1 -0
- package/dist/telemetry/TelemetryCapture.js +263 -0
- package/dist/telemetry/TelemetryCapture.test.d.ts +7 -0
- package/dist/telemetry/TelemetryCapture.test.d.ts.map +1 -0
- package/dist/telemetry/TelemetryCapture.test.js +396 -0
- package/dist/telemetry-example.d.ts +33 -0
- package/dist/telemetry-example.d.ts.map +1 -0
- package/dist/telemetry-example.js +124 -0
- package/package.json +1 -1
- package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts +0 -60
- package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts.map +0 -1
- package/dist/adapters/websocket/WebSocketTransportAdapter.js +0 -386
package/dist/index.mjs
CHANGED
|
@@ -2856,6 +2856,134 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
2856
2856
|
}
|
|
2857
2857
|
}
|
|
2858
2858
|
});
|
|
2859
|
+
// src/abstractions/RoomManager.ts
|
|
2860
|
+
class RoomManager {
|
|
2861
|
+
rooms = new Map;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2864
|
+
// src/abstractions/DefaultRoomManager.ts
|
|
2865
|
+
class DefaultRoomManager extends RoomManager {
|
|
2866
|
+
async createRoom(id, config) {
|
|
2867
|
+
const room = {
|
|
2868
|
+
id,
|
|
2869
|
+
name: config.name || id,
|
|
2870
|
+
createdAt: Date.now(),
|
|
2871
|
+
maxUsers: config.maxUsers,
|
|
2872
|
+
maxHistory: config.maxHistory,
|
|
2873
|
+
permissions: config.permissions,
|
|
2874
|
+
metadata: config.metadata || {}
|
|
2875
|
+
};
|
|
2876
|
+
const roomState = {
|
|
2877
|
+
room,
|
|
2878
|
+
users: new Map,
|
|
2879
|
+
eventHistory: [],
|
|
2880
|
+
locks: new Map
|
|
2881
|
+
};
|
|
2882
|
+
this.rooms.set(id, roomState);
|
|
2883
|
+
return room;
|
|
2884
|
+
}
|
|
2885
|
+
async deleteRoom(id) {
|
|
2886
|
+
this.rooms.delete(id);
|
|
2887
|
+
}
|
|
2888
|
+
async joinRoom(roomId, user) {
|
|
2889
|
+
const roomState = this.rooms.get(roomId);
|
|
2890
|
+
if (!roomState) {
|
|
2891
|
+
throw new Error(`Room ${roomId} not found`);
|
|
2892
|
+
}
|
|
2893
|
+
if (roomState.room.maxUsers && roomState.users.size >= roomState.room.maxUsers) {
|
|
2894
|
+
throw new Error(`Room ${roomId} is full`);
|
|
2895
|
+
}
|
|
2896
|
+
roomState.users.set(user.id, user);
|
|
2897
|
+
}
|
|
2898
|
+
async leaveRoom(roomId, userId) {
|
|
2899
|
+
const roomState = this.rooms.get(roomId);
|
|
2900
|
+
if (!roomState) {
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
roomState.users.delete(userId);
|
|
2904
|
+
}
|
|
2905
|
+
async broadcastToRoom(roomId, event, _excludeUserId) {
|
|
2906
|
+
const roomState = this.rooms.get(roomId);
|
|
2907
|
+
if (!roomState) {
|
|
2908
|
+
throw new Error(`Room ${roomId} not found`);
|
|
2909
|
+
}
|
|
2910
|
+
await this.addEventToHistory(roomId, event);
|
|
2911
|
+
}
|
|
2912
|
+
async getRoomState(roomId) {
|
|
2913
|
+
return this.rooms.get(roomId) || null;
|
|
2914
|
+
}
|
|
2915
|
+
async getUsersInRoom(roomId) {
|
|
2916
|
+
const roomState = this.rooms.get(roomId);
|
|
2917
|
+
if (!roomState) {
|
|
2918
|
+
return [];
|
|
2919
|
+
}
|
|
2920
|
+
return Array.from(roomState.users.values());
|
|
2921
|
+
}
|
|
2922
|
+
async addEventToHistory(roomId, event) {
|
|
2923
|
+
const roomState = this.rooms.get(roomId);
|
|
2924
|
+
if (!roomState) {
|
|
2925
|
+
throw new Error(`Room ${roomId} not found`);
|
|
2926
|
+
}
|
|
2927
|
+
roomState.eventHistory.push(event);
|
|
2928
|
+
if (roomState.room.maxHistory && roomState.eventHistory.length > roomState.room.maxHistory) {
|
|
2929
|
+
roomState.eventHistory = roomState.eventHistory.slice(-roomState.room.maxHistory);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
async getEventHistory(roomId, limit) {
|
|
2933
|
+
const roomState = this.rooms.get(roomId);
|
|
2934
|
+
if (!roomState) {
|
|
2935
|
+
return [];
|
|
2936
|
+
}
|
|
2937
|
+
const history = roomState.eventHistory;
|
|
2938
|
+
return limit ? history.slice(-limit) : history;
|
|
2939
|
+
}
|
|
2940
|
+
async updateUserStatus(roomId, userId, status) {
|
|
2941
|
+
const roomState = this.rooms.get(roomId);
|
|
2942
|
+
if (!roomState) {
|
|
2943
|
+
throw new Error(`Room ${roomId} not found`);
|
|
2944
|
+
}
|
|
2945
|
+
const user = roomState.users.get(userId);
|
|
2946
|
+
if (user) {
|
|
2947
|
+
user.status = status;
|
|
2948
|
+
user.lastActivity = Date.now();
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
// src/abstractions/ConnectedRoomManager.ts
|
|
2954
|
+
class ConnectedRoomManager extends DefaultRoomManager {
|
|
2955
|
+
sendToClient;
|
|
2956
|
+
getClientIdsInRoom;
|
|
2957
|
+
constructor(sendToClient, getClientIdsInRoom) {
|
|
2958
|
+
super();
|
|
2959
|
+
this.sendToClient = sendToClient;
|
|
2960
|
+
this.getClientIdsInRoom = getClientIdsInRoom;
|
|
2961
|
+
}
|
|
2962
|
+
async broadcastToRoom(roomId, event, excludeUserId) {
|
|
2963
|
+
const roomState = this.rooms.get(roomId);
|
|
2964
|
+
if (!roomState) {
|
|
2965
|
+
throw new Error(`Room ${roomId} not found`);
|
|
2966
|
+
}
|
|
2967
|
+
await this.addEventToHistory(roomId, event);
|
|
2968
|
+
const users = Array.from(roomState.users.values());
|
|
2969
|
+
const sendPromises = [];
|
|
2970
|
+
for (const user of users) {
|
|
2971
|
+
if (excludeUserId && user.id === excludeUserId) {
|
|
2972
|
+
continue;
|
|
2973
|
+
}
|
|
2974
|
+
const clientIds = this.getClientIdsInRoom(roomId, user.id);
|
|
2975
|
+
for (const clientId of clientIds) {
|
|
2976
|
+
sendPromises.push(this.sendToClient(clientId, {
|
|
2977
|
+
type: "event_received",
|
|
2978
|
+
event
|
|
2979
|
+
}).catch((error) => {
|
|
2980
|
+
console.error(`[ConnectedRoomManager] Failed to send event to client ${clientId}:`, error);
|
|
2981
|
+
}));
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
await Promise.all(sendPromises);
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2859
2987
|
// src/abstractions/LockManager.ts
|
|
2860
2988
|
class LockManager {
|
|
2861
2989
|
lockState = {
|
|
@@ -3374,99 +3502,6 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3374
3502
|
return this.userPresences.size + this.gracePeriodEntries.size;
|
|
3375
3503
|
}
|
|
3376
3504
|
}
|
|
3377
|
-
// src/abstractions/RoomManager.ts
|
|
3378
|
-
class RoomManager {
|
|
3379
|
-
rooms = new Map;
|
|
3380
|
-
}
|
|
3381
|
-
|
|
3382
|
-
// src/abstractions/DefaultRoomManager.ts
|
|
3383
|
-
class DefaultRoomManager extends RoomManager {
|
|
3384
|
-
async createRoom(id, config) {
|
|
3385
|
-
const room = {
|
|
3386
|
-
id,
|
|
3387
|
-
name: config.name || id,
|
|
3388
|
-
createdAt: Date.now(),
|
|
3389
|
-
maxUsers: config.maxUsers,
|
|
3390
|
-
maxHistory: config.maxHistory,
|
|
3391
|
-
permissions: config.permissions,
|
|
3392
|
-
metadata: config.metadata || {}
|
|
3393
|
-
};
|
|
3394
|
-
const roomState = {
|
|
3395
|
-
room,
|
|
3396
|
-
users: new Map,
|
|
3397
|
-
eventHistory: [],
|
|
3398
|
-
locks: new Map
|
|
3399
|
-
};
|
|
3400
|
-
this.rooms.set(id, roomState);
|
|
3401
|
-
return room;
|
|
3402
|
-
}
|
|
3403
|
-
async deleteRoom(id) {
|
|
3404
|
-
this.rooms.delete(id);
|
|
3405
|
-
}
|
|
3406
|
-
async joinRoom(roomId, user) {
|
|
3407
|
-
const roomState = this.rooms.get(roomId);
|
|
3408
|
-
if (!roomState) {
|
|
3409
|
-
throw new Error(`Room ${roomId} not found`);
|
|
3410
|
-
}
|
|
3411
|
-
if (roomState.room.maxUsers && roomState.users.size >= roomState.room.maxUsers) {
|
|
3412
|
-
throw new Error(`Room ${roomId} is full`);
|
|
3413
|
-
}
|
|
3414
|
-
roomState.users.set(user.id, user);
|
|
3415
|
-
}
|
|
3416
|
-
async leaveRoom(roomId, userId) {
|
|
3417
|
-
const roomState = this.rooms.get(roomId);
|
|
3418
|
-
if (!roomState) {
|
|
3419
|
-
return;
|
|
3420
|
-
}
|
|
3421
|
-
roomState.users.delete(userId);
|
|
3422
|
-
}
|
|
3423
|
-
async broadcastToRoom(roomId, event, _excludeUserId) {
|
|
3424
|
-
const roomState = this.rooms.get(roomId);
|
|
3425
|
-
if (!roomState) {
|
|
3426
|
-
throw new Error(`Room ${roomId} not found`);
|
|
3427
|
-
}
|
|
3428
|
-
await this.addEventToHistory(roomId, event);
|
|
3429
|
-
}
|
|
3430
|
-
async getRoomState(roomId) {
|
|
3431
|
-
return this.rooms.get(roomId) || null;
|
|
3432
|
-
}
|
|
3433
|
-
async getUsersInRoom(roomId) {
|
|
3434
|
-
const roomState = this.rooms.get(roomId);
|
|
3435
|
-
if (!roomState) {
|
|
3436
|
-
return [];
|
|
3437
|
-
}
|
|
3438
|
-
return Array.from(roomState.users.values());
|
|
3439
|
-
}
|
|
3440
|
-
async addEventToHistory(roomId, event) {
|
|
3441
|
-
const roomState = this.rooms.get(roomId);
|
|
3442
|
-
if (!roomState) {
|
|
3443
|
-
throw new Error(`Room ${roomId} not found`);
|
|
3444
|
-
}
|
|
3445
|
-
roomState.eventHistory.push(event);
|
|
3446
|
-
if (roomState.room.maxHistory && roomState.eventHistory.length > roomState.room.maxHistory) {
|
|
3447
|
-
roomState.eventHistory = roomState.eventHistory.slice(-roomState.room.maxHistory);
|
|
3448
|
-
}
|
|
3449
|
-
}
|
|
3450
|
-
async getEventHistory(roomId, limit) {
|
|
3451
|
-
const roomState = this.rooms.get(roomId);
|
|
3452
|
-
if (!roomState) {
|
|
3453
|
-
return [];
|
|
3454
|
-
}
|
|
3455
|
-
const history = roomState.eventHistory;
|
|
3456
|
-
return limit ? history.slice(-limit) : history;
|
|
3457
|
-
}
|
|
3458
|
-
async updateUserStatus(roomId, userId, status) {
|
|
3459
|
-
const roomState = this.rooms.get(roomId);
|
|
3460
|
-
if (!roomState) {
|
|
3461
|
-
throw new Error(`Room ${roomId} not found`);
|
|
3462
|
-
}
|
|
3463
|
-
const user = roomState.users.get(userId);
|
|
3464
|
-
if (user) {
|
|
3465
|
-
user.status = status;
|
|
3466
|
-
user.lastActivity = Date.now();
|
|
3467
|
-
}
|
|
3468
|
-
}
|
|
3469
|
-
}
|
|
3470
3505
|
// src/abstractions/EventEmitter.ts
|
|
3471
3506
|
class TypedEventEmitter {
|
|
3472
3507
|
listeners = new Map;
|
|
@@ -6274,6 +6309,7 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6274
6309
|
const client = {
|
|
6275
6310
|
id: payload.clientId,
|
|
6276
6311
|
userId: payload.userId || "",
|
|
6312
|
+
deviceId: payload.clientId,
|
|
6277
6313
|
roomIds,
|
|
6278
6314
|
get roomId() {
|
|
6279
6315
|
return roomIds.size > 0 ? roomIds.values().next().value || null : null;
|
|
@@ -6353,6 +6389,7 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6353
6389
|
const client = {
|
|
6354
6390
|
id: clientId,
|
|
6355
6391
|
userId: "",
|
|
6392
|
+
deviceId: clientId,
|
|
6356
6393
|
roomIds,
|
|
6357
6394
|
get roomId() {
|
|
6358
6395
|
return roomIds.size > 0 ? roomIds.values().next().value || null : null;
|
|
@@ -6381,10 +6418,10 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6381
6418
|
}
|
|
6382
6419
|
if (this.presenceManager?.isEnabled() && client.userId) {
|
|
6383
6420
|
try {
|
|
6384
|
-
const presence = await this.presenceManager.disconnectDevice(client.userId,
|
|
6421
|
+
const presence = await this.presenceManager.disconnectDevice(client.userId, client.deviceId);
|
|
6385
6422
|
await this.emit("presence_device_disconnected", {
|
|
6386
6423
|
userId: client.userId,
|
|
6387
|
-
deviceId:
|
|
6424
|
+
deviceId: client.deviceId,
|
|
6388
6425
|
timestamp: Date.now()
|
|
6389
6426
|
});
|
|
6390
6427
|
const presenceConfig = this.presenceManager.getConfig();
|
|
@@ -6393,7 +6430,7 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6393
6430
|
type: "presence:user_offline",
|
|
6394
6431
|
payload: {
|
|
6395
6432
|
userId: client.userId,
|
|
6396
|
-
deviceId:
|
|
6433
|
+
deviceId: client.deviceId,
|
|
6397
6434
|
status: presence?.status || "offline",
|
|
6398
6435
|
gracePeriod: presenceConfig.gracePeriod
|
|
6399
6436
|
}
|
|
@@ -6407,6 +6444,17 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6407
6444
|
}
|
|
6408
6445
|
}
|
|
6409
6446
|
for (const roomId of client.roomIds) {
|
|
6447
|
+
try {
|
|
6448
|
+
await this.experimental.broadcastWhere((c) => c.roomIds.has(roomId) && c.id !== clientId, {
|
|
6449
|
+
type: "member_left",
|
|
6450
|
+
payload: {
|
|
6451
|
+
roomId,
|
|
6452
|
+
userId: client.userId,
|
|
6453
|
+
clientId,
|
|
6454
|
+
timestamp: Date.now()
|
|
6455
|
+
}
|
|
6456
|
+
});
|
|
6457
|
+
} catch {}
|
|
6410
6458
|
await this.roomManager.leaveRoom(roomId, client.userId);
|
|
6411
6459
|
await this.emit("client_left_room", { clientId, roomId });
|
|
6412
6460
|
}
|
|
@@ -6423,7 +6471,7 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6423
6471
|
return;
|
|
6424
6472
|
}
|
|
6425
6473
|
if (this.presenceManager?.isEnabled() && client.userId && client.authenticated) {
|
|
6426
|
-
await this.updatePresenceActivity(client.userId,
|
|
6474
|
+
await this.updatePresenceActivity(client.userId, client.deviceId, "message");
|
|
6427
6475
|
}
|
|
6428
6476
|
switch (message.type) {
|
|
6429
6477
|
case "authenticate":
|
|
@@ -6600,6 +6648,17 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6600
6648
|
if (!client.roomIds.has(roomId)) {
|
|
6601
6649
|
continue;
|
|
6602
6650
|
}
|
|
6651
|
+
try {
|
|
6652
|
+
await this.experimental.broadcastWhere((c) => c.roomIds.has(roomId) && c.id !== clientId, {
|
|
6653
|
+
type: "member_left",
|
|
6654
|
+
payload: {
|
|
6655
|
+
roomId,
|
|
6656
|
+
userId: client.userId,
|
|
6657
|
+
clientId,
|
|
6658
|
+
timestamp: Date.now()
|
|
6659
|
+
}
|
|
6660
|
+
});
|
|
6661
|
+
} catch {}
|
|
6603
6662
|
await this.roomManager.leaveRoom(roomId, client.userId);
|
|
6604
6663
|
client.roomIds.delete(roomId);
|
|
6605
6664
|
await this.emit("client_left_room", { clientId, roomId });
|
|
@@ -6764,8 +6823,24 @@ class BaseServer extends TypedEventEmitter {
|
|
|
6764
6823
|
getClientIdsForUser(userId) {
|
|
6765
6824
|
return Array.from(this.userClientMap.get(userId) || []);
|
|
6766
6825
|
}
|
|
6826
|
+
getClientIdsInRoom(roomId, userId) {
|
|
6827
|
+
const allClientIds = this.getClientIdsForUser(userId);
|
|
6828
|
+
return allClientIds.filter((clientId) => {
|
|
6829
|
+
const client = this.clients.get(clientId);
|
|
6830
|
+
return client && client.roomIds.has(roomId);
|
|
6831
|
+
});
|
|
6832
|
+
}
|
|
6767
6833
|
getDeviceIdFromClientId(clientId) {
|
|
6768
|
-
|
|
6834
|
+
const client = this.clients.get(clientId);
|
|
6835
|
+
return client?.deviceId ?? clientId;
|
|
6836
|
+
}
|
|
6837
|
+
setClientDeviceId(clientId, deviceId) {
|
|
6838
|
+
const client = this.clients.get(clientId);
|
|
6839
|
+
if (client) {
|
|
6840
|
+
client.deviceId = deviceId;
|
|
6841
|
+
return true;
|
|
6842
|
+
}
|
|
6843
|
+
return false;
|
|
6769
6844
|
}
|
|
6770
6845
|
}
|
|
6771
6846
|
// src/server/ServerBuilder.ts
|
|
@@ -6857,6 +6932,11 @@ class ServerBuilder {
|
|
|
6857
6932
|
}
|
|
6858
6933
|
};
|
|
6859
6934
|
const server = new BaseServer(config);
|
|
6935
|
+
if (this.roomManager.constructor.name === "DefaultRoomManager") {
|
|
6936
|
+
const connectedManager = new ConnectedRoomManager((clientId, message) => server.sendToClient(clientId, message), (roomId, userId) => server.getClientIdsInRoom(roomId, userId));
|
|
6937
|
+
connectedManager.rooms = this.roomManager.rooms;
|
|
6938
|
+
server.roomManager = connectedManager;
|
|
6939
|
+
}
|
|
6860
6940
|
if (this.presenceManager instanceof DefaultPresenceManager) {
|
|
6861
6941
|
this.presenceManager.setServer(server);
|
|
6862
6942
|
}
|
|
@@ -6916,10 +6996,11 @@ export {
|
|
|
6916
6996
|
DefaultRoomManager,
|
|
6917
6997
|
DefaultPresenceManager,
|
|
6918
6998
|
DefaultLockManager,
|
|
6999
|
+
ConnectedRoomManager,
|
|
6919
7000
|
ClientBuilder,
|
|
6920
7001
|
BrowserWebSocketTransportAdapter,
|
|
6921
7002
|
BaseServer,
|
|
6922
7003
|
BaseClient
|
|
6923
7004
|
};
|
|
6924
7005
|
|
|
6925
|
-
//# debugId=
|
|
7006
|
+
//# debugId=A5E31B6ED779287364756E2164756E21
|