@principal-ai/control-tower-core 0.1.7 → 0.1.8

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.
@@ -11,10 +11,12 @@ class MockTransportAdapter {
11
11
  this.simulateLatency = 0;
12
12
  this.shouldFailConnection = false;
13
13
  this.connectedUrl = null;
14
+ this.connectionAttempts = 0;
14
15
  this.simulateLatency = options?.simulateLatency ?? 0;
15
16
  this.shouldFailConnection = options?.shouldFailConnection ?? false;
16
17
  }
17
18
  async connect(url, _options) {
19
+ this.connectionAttempts++;
18
20
  if (this.shouldFailConnection) {
19
21
  this.state = 'disconnected';
20
22
  const error = new Error('Mock connection failed');
@@ -68,8 +70,8 @@ class MockTransportAdapter {
68
70
  return this.state === 'connected';
69
71
  }
70
72
  // Test helper methods
71
- simulateMessage(message) {
72
- if (this.state !== 'connected') {
73
+ simulateMessage(message, bypassConnectionCheck = false) {
74
+ if (!bypassConnectionCheck && this.state !== 'connected') {
73
75
  throw new Error('Cannot simulate message when not connected');
74
76
  }
75
77
  this.messageHandlers.forEach(handler => handler(message));
@@ -90,5 +92,102 @@ class MockTransportAdapter {
90
92
  getConnectedUrl() {
91
93
  return this.connectedUrl;
92
94
  }
95
+ getConnectionAttempts() {
96
+ return this.connectionAttempts;
97
+ }
98
+ resetConnectionAttempts() {
99
+ this.connectionAttempts = 0;
100
+ }
101
+ // Additional test helper methods for two-tier architecture testing
102
+ /**
103
+ * Simulate a client connection with authentication state
104
+ * Note: This bypasses the connected state check for testing purposes
105
+ */
106
+ async simulateConnection(clientId, options = {}) {
107
+ // Set transport to connected state if not already
108
+ if (this.state !== 'connected') {
109
+ this.state = 'connected';
110
+ }
111
+ const message = {
112
+ id: `conn-${clientId}`,
113
+ type: 'connection',
114
+ payload: {
115
+ clientId,
116
+ authenticated: options.authenticated ?? false,
117
+ userId: options.userId,
118
+ metadata: options.metadata
119
+ },
120
+ timestamp: Date.now()
121
+ };
122
+ // Use simulateMessage with bypass flag
123
+ this.simulateMessage(message, true);
124
+ }
125
+ /**
126
+ * Simulate a client disconnection
127
+ */
128
+ async simulateDisconnect(clientId, reason = 'Normal closure') {
129
+ // Send a disconnect message to the server for this specific client
130
+ const message = {
131
+ id: `disconnect-${clientId}`,
132
+ type: 'disconnect',
133
+ payload: {
134
+ clientId,
135
+ reason
136
+ },
137
+ timestamp: Date.now()
138
+ };
139
+ this.simulateMessage(message, true);
140
+ }
141
+ /**
142
+ * Simulate sending a message from a client to the server
143
+ * Properly wraps the message with clientId in payload for server routing
144
+ *
145
+ * @param clientId - The client sending the message
146
+ * @param messageType - The message type (e.g., 'join_room', 'leave_room', 'broadcast_event')
147
+ * @param messagePayload - The message payload
148
+ */
149
+ async simulateClientMessage(clientId, messageType, messagePayload = {}) {
150
+ const message = {
151
+ id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
152
+ type: 'server_message',
153
+ payload: {
154
+ clientId,
155
+ type: messageType,
156
+ ...messagePayload
157
+ },
158
+ timestamp: Date.now()
159
+ };
160
+ this.simulateMessage(message, true);
161
+ }
162
+ /**
163
+ * Get all messages sent to a specific client
164
+ * This filters the message queue for messages addressed to the given client
165
+ */
166
+ getSentMessages(clientId) {
167
+ return this.messageQueue
168
+ .filter(msg => {
169
+ const payload = msg.payload;
170
+ return payload?.clientId === clientId;
171
+ })
172
+ .map(msg => {
173
+ const { clientId: _, ...rest } = msg.payload;
174
+ return rest;
175
+ });
176
+ }
177
+ /**
178
+ * Simulate an incoming message from the server to the client
179
+ * This is used in client tests to mock server responses
180
+ * @param message - The message to send to the client
181
+ */
182
+ simulateIncomingMessage(message) {
183
+ // Ensure message has required Message fields
184
+ const fullMessage = {
185
+ id: message.id || `msg-${Date.now()}`,
186
+ type: message.type,
187
+ payload: message.payload || {},
188
+ timestamp: message.timestamp || Date.now()
189
+ };
190
+ this.messageHandlers.forEach(handler => handler(fullMessage));
191
+ }
93
192
  }
94
193
  exports.MockTransportAdapter = MockTransportAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocketTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EAGb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEhD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IAGrD,OAAO,CAAC,GAAG,CAAC,CAAkB;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAG3B,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,OAAO,CAAC,WAAW,CAAC,CAAkB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAS;IAG/B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,IAAI,CAA8C;IAG1D,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,CAAC,EAAE,wBAAwB;IAU7C,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAYlC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAE,MAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC7E,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BpD,gBAAgB;YA6EhB,mBAAmB;YAuCnB,iBAAiB;IA4E/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,YAAY;IAMd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,mBAAmB,IAAI,gBAAgB,EAAE;IAIzC,uBAAuB,IAAI,gBAAgB,EAAE;IAI7C,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,YAAY,GAAG,aAAa;IAIvC,cAAc,IAAI,OAAO;IAIzB,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"WebSocketTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EAGb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEhD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IAGrD,OAAO,CAAC,GAAG,CAAC,CAAkB;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAG3B,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,OAAO,CAAC,WAAW,CAAC,CAAkB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAS;IAG/B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,IAAI,CAA8C;IAG1D,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,CAAC,EAAE,wBAAwB;IAU7C,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAclC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAE,MAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC7E,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BpD,gBAAgB;YA6EhB,mBAAmB;YAuCnB,iBAAiB;IA4E/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,YAAY;IAMd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,mBAAmB,IAAI,gBAAgB,EAAE;IAIzC,uBAAuB,IAAI,gBAAgB,EAAE;IAI7C,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,YAAY,GAAG,aAAa;IAIvC,cAAc,IAAI,OAAO;IAIzB,OAAO,CAAC,UAAU;CAGnB"}
@@ -21,11 +21,13 @@ class WebSocketTransportAdapter {
21
21
  // Set the auth adapter
22
22
  setAuthAdapter(auth) {
23
23
  this.authAdapter = auth;
24
- // Update requireAuth based on auth adapter's preference
25
- if (auth.isAuthRequired) {
24
+ // Use auth adapter's preference only if requireAuth is not already true
25
+ // This allows explicit requireAuth: true in config to take precedence
26
+ if (auth.isAuthRequired && !this.config.requireAuth) {
26
27
  this.config.requireAuth = auth.isAuthRequired();
27
28
  }
28
- if (auth.getAuthTimeout) {
29
+ // For authTimeout, use adapter's value if not explicitly set (not matching default)
30
+ if (auth.getAuthTimeout && this.config.authTimeout === 5000) {
29
31
  this.config.authTimeout = auth.getAuthTimeout();
30
32
  }
31
33
  }