@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.
Files changed (42) hide show
  1. package/dist/abstractions/ConnectedRoomManager.d.ts +22 -0
  2. package/dist/abstractions/ConnectedRoomManager.d.ts.map +1 -0
  3. package/dist/abstractions/ConnectedRoomManager.js +56 -0
  4. package/dist/abstractions/index.d.ts +1 -0
  5. package/dist/abstractions/index.d.ts.map +1 -1
  6. package/dist/abstractions/index.js +3 -1
  7. package/dist/generated/client-connection-auth.types.d.ts +312 -0
  8. package/dist/generated/client-connection-auth.types.d.ts.map +1 -0
  9. package/dist/generated/client-connection-auth.types.js +11 -0
  10. package/dist/generated/control-tower-execution.types.d.ts +445 -0
  11. package/dist/generated/control-tower-execution.types.d.ts.map +1 -0
  12. package/dist/generated/control-tower-execution.types.js +11 -0
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -1
  16. package/dist/index.js.map +8 -7
  17. package/dist/index.mjs +180 -99
  18. package/dist/index.mjs.map +8 -7
  19. package/dist/server/BaseServer.d.ts +30 -2
  20. package/dist/server/BaseServer.d.ts.map +1 -1
  21. package/dist/server/BaseServer.js +77 -8
  22. package/dist/server/ServerBuilder.d.ts.map +1 -1
  23. package/dist/server/ServerBuilder.js +11 -0
  24. package/dist/telemetry/EventValidationIntegration.d.ts +135 -0
  25. package/dist/telemetry/EventValidationIntegration.d.ts.map +1 -0
  26. package/dist/telemetry/EventValidationIntegration.js +253 -0
  27. package/dist/telemetry/EventValidationIntegration.test.d.ts +7 -0
  28. package/dist/telemetry/EventValidationIntegration.test.d.ts.map +1 -0
  29. package/dist/telemetry/EventValidationIntegration.test.js +322 -0
  30. package/dist/telemetry/TelemetryCapture.d.ts +268 -0
  31. package/dist/telemetry/TelemetryCapture.d.ts.map +1 -0
  32. package/dist/telemetry/TelemetryCapture.js +263 -0
  33. package/dist/telemetry/TelemetryCapture.test.d.ts +7 -0
  34. package/dist/telemetry/TelemetryCapture.test.d.ts.map +1 -0
  35. package/dist/telemetry/TelemetryCapture.test.js +396 -0
  36. package/dist/telemetry-example.d.ts +33 -0
  37. package/dist/telemetry-example.d.ts.map +1 -0
  38. package/dist/telemetry-example.js +124 -0
  39. package/package.json +1 -1
  40. package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts +0 -60
  41. package/dist/adapters/websocket/WebSocketTransportAdapter.d.ts.map +0 -1
  42. 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, clientId);
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: clientId,
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: clientId,
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, clientId, "message");
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
- return clientId;
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=94389897A03B4D7064756E2164756E21
7006
+ //# debugId=A5E31B6ED779287364756E2164756E21