@@ -7,6 +7,35 @@ declare module "cloudflare:test" {
77 interface ProvidedEnv extends Env { }
88}
99
10+ // Message types used in tests
11+ interface StateMessage {
12+ type : MessageType . CF_AGENT_STATE ;
13+ state : { count ?: number } ;
14+ }
15+
16+ interface StateErrorMessage {
17+ type : MessageType . CF_AGENT_STATE_ERROR ;
18+ error : string ;
19+ }
20+
21+ interface RpcMessage {
22+ type : MessageType . RPC ;
23+ id : string ;
24+ success ?: boolean ;
25+ result ?: unknown ;
26+ }
27+
28+ type TestMessage = StateMessage | StateErrorMessage | RpcMessage ;
29+
30+ function isTestMessage ( data : unknown ) : data is TestMessage {
31+ return (
32+ typeof data === "object" &&
33+ data !== null &&
34+ "type" in data &&
35+ typeof ( data as TestMessage ) . type === "string"
36+ ) ;
37+ }
38+
1039async function connectWS ( path : string ) {
1140 const ctx = createExecutionContext ( ) ;
1241 const req = new Request ( `http://example.com${ path } ` , {
@@ -20,17 +49,17 @@ async function connectWS(path: string) {
2049 return { ws, ctx } ;
2150}
2251
23- function waitForMessage (
52+ function waitForMessage < T extends TestMessage > (
2453 ws : WebSocket ,
25- predicate : ( data : unknown ) => boolean
26- ) : Promise < unknown > {
54+ predicate : ( data : TestMessage ) => boolean
55+ ) : Promise < T > {
2756 return new Promise ( ( resolve ) => {
2857 const handler = ( e : MessageEvent ) => {
2958 try {
30- const data = JSON . parse ( e . data as string ) ;
31- if ( predicate ( data ) ) {
59+ const data : unknown = JSON . parse ( e . data as string ) ;
60+ if ( isTestMessage ( data ) && predicate ( data ) ) {
3261 ws . removeEventListener ( "message" , handler ) ;
33- resolve ( data ) ;
62+ resolve ( data as T ) ;
3463 }
3564 } catch {
3665 // Ignore parse errors
@@ -49,9 +78,9 @@ describe("Readonly Connections", () => {
4978 ) ;
5079
5180 // Wait for initial state message
52- await waitForMessage (
81+ await waitForMessage < StateMessage > (
5382 ws1 ,
54- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
83+ ( data ) => data . type === MessageType . CF_AGENT_STATE
5584 ) ;
5685
5786 ws1 . close ( ) ;
@@ -61,9 +90,9 @@ describe("Readonly Connections", () => {
6190 `/agents/test-readonly-agent/${ room } ?readonly=false`
6291 ) ;
6392
64- await waitForMessage (
93+ await waitForMessage < StateMessage > (
6594 ws2 ,
66- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
95+ ( data ) => data . type === MessageType . CF_AGENT_STATE
6796 ) ;
6897
6998 // Test passed - connections were established with different readonly query params
@@ -79,15 +108,15 @@ describe("Readonly Connections", () => {
79108 ) ;
80109
81110 // Wait for initial state
82- await waitForMessage (
111+ await waitForMessage < StateMessage > (
83112 ws ,
84- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
113+ ( data ) => data . type === MessageType . CF_AGENT_STATE
85114 ) ;
86115
87116 // Try to update state from readonly connection
88- const errorPromise = waitForMessage (
117+ const errorPromise = waitForMessage < StateErrorMessage > (
89118 ws ,
90- ( data : any ) => data . type === MessageType . CF_AGENT_STATE_ERROR
119+ ( data ) => data . type === MessageType . CF_AGENT_STATE_ERROR
91120 ) ;
92121
93122 ws . send (
@@ -97,7 +126,7 @@ describe("Readonly Connections", () => {
97126 } )
98127 ) ;
99128
100- const errorMsg = ( await errorPromise ) as any ;
129+ const errorMsg = await errorPromise ;
101130 expect ( errorMsg . type ) . toBe ( MessageType . CF_AGENT_STATE_ERROR ) ;
102131 expect ( errorMsg . error ) . toBe ( "Connection is readonly" ) ;
103132
@@ -111,10 +140,10 @@ describe("Readonly Connections", () => {
111140 ) ;
112141
113142 // Wait for initial state
114- const initialState = ( await waitForMessage (
143+ const initialState = await waitForMessage < StateMessage > (
115144 ws ,
116- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
117- ) ) as any ;
145+ ( data ) => data . type === MessageType . CF_AGENT_STATE
146+ ) ;
118147
119148 expect ( initialState . state ) . toBeDefined ( ) ;
120149
@@ -130,16 +159,16 @@ describe("Readonly Connections", () => {
130159 ) ;
131160
132161 // Wait for initial state
133- await waitForMessage (
162+ await waitForMessage < StateMessage > (
134163 ws ,
135- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
164+ ( data ) => data . type === MessageType . CF_AGENT_STATE
136165 ) ;
137166
138167 // Call RPC method from readonly connection
139168 const rpcId = Math . random ( ) . toString ( 36 ) . slice ( 2 ) ;
140- const rpcPromise = waitForMessage (
169+ const rpcPromise = waitForMessage < RpcMessage > (
141170 ws ,
142- ( data : any ) => data . type === MessageType . RPC && data . id === rpcId
171+ ( data ) => data . type === MessageType . RPC && data . id === rpcId
143172 ) ;
144173
145174 ws . send (
@@ -151,7 +180,7 @@ describe("Readonly Connections", () => {
151180 } )
152181 ) ;
153182
154- const rpcMsg = ( await rpcPromise ) as any ;
183+ const rpcMsg = await rpcPromise ;
155184 expect ( rpcMsg . success ) . toBe ( true ) ;
156185 expect ( rpcMsg . result ) . toBe ( 1 ) ;
157186
@@ -167,9 +196,9 @@ describe("Readonly Connections", () => {
167196 ) ;
168197
169198 // Wait for initial state
170- await waitForMessage (
199+ await waitForMessage < StateMessage > (
171200 ws ,
172- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
201+ ( data ) => data . type === MessageType . CF_AGENT_STATE
173202 ) ;
174203
175204 // Call an RPC method to verify connection works
@@ -183,10 +212,10 @@ describe("Readonly Connections", () => {
183212 } )
184213 ) ;
185214
186- const rpcMsg = ( await waitForMessage (
215+ const rpcMsg = await waitForMessage < RpcMessage > (
187216 ws ,
188- ( data : any ) => data . type === MessageType . RPC && data . id === rpcId
189- ) ) as any ;
217+ ( data ) => data . type === MessageType . RPC && data . id === rpcId
218+ ) ;
190219
191220 expect ( rpcMsg . success ) . toBe ( true ) ;
192221 expect ( rpcMsg . result ) . toBeDefined ( ) ;
@@ -203,9 +232,9 @@ describe("Readonly Connections", () => {
203232 ) ;
204233
205234 // Wait for connection
206- await waitForMessage (
235+ await waitForMessage < StateMessage > (
207236 ws ,
208- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
237+ ( data ) => data . type === MessageType . CF_AGENT_STATE
209238 ) ;
210239
211240 // Check that readonly status is in the database
@@ -219,14 +248,14 @@ describe("Readonly Connections", () => {
219248 } )
220249 ) ;
221250
222- const dbResult = ( await waitForMessage (
251+ const dbResult = await waitForMessage < RpcMessage > (
223252 ws ,
224- ( data : any ) => data . type === MessageType . RPC && data . id === checkDbId
225- ) ) as any ;
253+ ( data ) => data . type === MessageType . RPC && data . id === checkDbId
254+ ) ;
226255
227256 // Should have at least one entry
228257 expect ( Array . isArray ( dbResult . result ) ) . toBe ( true ) ;
229- expect ( dbResult . result . length ) . toBeGreaterThan ( 0 ) ;
258+ expect ( ( dbResult . result as unknown [ ] ) . length ) . toBeGreaterThan ( 0 ) ;
230259
231260 ws . close ( ) ;
232261 } ) ;
@@ -239,9 +268,9 @@ describe("Readonly Connections", () => {
239268 `/agents/test-readonly-agent/${ room } ?readonly=true`
240269 ) ;
241270
242- await waitForMessage (
271+ await waitForMessage < StateMessage > (
243272 ws1 ,
244- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
273+ ( data ) => data . type === MessageType . CF_AGENT_STATE
245274 ) ;
246275
247276 // Close connection (simulates hibernation scenario)
@@ -255,15 +284,15 @@ describe("Readonly Connections", () => {
255284 `/agents/test-readonly-agent/${ room } ?readonly=true`
256285 ) ;
257286
258- await waitForMessage (
287+ await waitForMessage < StateMessage > (
259288 ws2 ,
260- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
289+ ( data ) => data . type === MessageType . CF_AGENT_STATE
261290 ) ;
262291
263292 // Try state update - should still be blocked
264- const errorPromise = waitForMessage (
293+ const errorPromise = waitForMessage < StateErrorMessage > (
265294 ws2 ,
266- ( data : any ) => data . type === MessageType . CF_AGENT_STATE_ERROR
295+ ( data ) => data . type === MessageType . CF_AGENT_STATE_ERROR
267296 ) ;
268297
269298 ws2 . send (
@@ -273,7 +302,7 @@ describe("Readonly Connections", () => {
273302 } )
274303 ) ;
275304
276- const errorMsg = ( await errorPromise ) as any ;
305+ const errorMsg = await errorPromise ;
277306 expect ( errorMsg . type ) . toBe ( MessageType . CF_AGENT_STATE_ERROR ) ;
278307
279308 ws2 . close ( ) ;
@@ -287,9 +316,9 @@ describe("Readonly Connections", () => {
287316 `/agents/test-readonly-agent/${ room } ?readonly=true`
288317 ) ;
289318
290- await waitForMessage (
319+ await waitForMessage < StateMessage > (
291320 ws ,
292- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
321+ ( data ) => data . type === MessageType . CF_AGENT_STATE
293322 ) ;
294323
295324 // Verify it's in the database
@@ -303,12 +332,12 @@ describe("Readonly Connections", () => {
303332 } )
304333 ) ;
305334
306- const dbResult1 = ( await waitForMessage (
335+ const dbResult1 = await waitForMessage < RpcMessage > (
307336 ws ,
308- ( data : any ) => data . type === MessageType . RPC && data . id === checkDbId1
309- ) ) as any ;
337+ ( data ) => data . type === MessageType . RPC && data . id === checkDbId1
338+ ) ;
310339
311- expect ( dbResult1 . result . length ) . toBeGreaterThan ( 0 ) ;
340+ expect ( ( dbResult1 . result as unknown [ ] ) . length ) . toBeGreaterThan ( 0 ) ;
312341
313342 // Close connection
314343 ws . close ( ) ;
@@ -321,9 +350,9 @@ describe("Readonly Connections", () => {
321350 `/agents/test-readonly-agent/${ room } ?readonly=false`
322351 ) ;
323352
324- await waitForMessage (
353+ await waitForMessage < StateMessage > (
325354 ws2 ,
326- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
355+ ( data ) => data . type === MessageType . CF_AGENT_STATE
327356 ) ;
328357
329358 const checkDbId2 = Math . random ( ) . toString ( 36 ) . slice ( 2 ) ;
@@ -336,10 +365,10 @@ describe("Readonly Connections", () => {
336365 } )
337366 ) ;
338367
339- const dbResult2 = ( await waitForMessage (
368+ const dbResult2 = await waitForMessage < RpcMessage > (
340369 ws2 ,
341- ( data : any ) => data . type === MessageType . RPC && data . id === checkDbId2
342- ) ) as any ;
370+ ( data ) => data . type === MessageType . RPC && data . id === checkDbId2
371+ ) ;
343372
344373 // Old connection should be cleaned up
345374 expect ( dbResult2 . result ) . toEqual ( [ ] ) ;
@@ -357,15 +386,15 @@ describe("Readonly Connections", () => {
357386 `/agents/test-readonly-agent/${ room } ?readonly=true`
358387 ) ;
359388
360- await waitForMessage (
389+ await waitForMessage < StateMessage > (
361390 ws1 ,
362- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
391+ ( data ) => data . type === MessageType . CF_AGENT_STATE
363392 ) ;
364393
365394 // ws1 (readonly) should not be able to update state
366- const errorPromise = waitForMessage (
395+ const errorPromise = waitForMessage < StateErrorMessage > (
367396 ws1 ,
368- ( data : any ) => data . type === MessageType . CF_AGENT_STATE_ERROR
397+ ( data ) => data . type === MessageType . CF_AGENT_STATE_ERROR
369398 ) ;
370399
371400 ws1 . send (
@@ -375,7 +404,7 @@ describe("Readonly Connections", () => {
375404 } )
376405 ) ;
377406
378- const errorMsg = ( await errorPromise ) as any ;
407+ const errorMsg = await errorPromise ;
379408 expect ( errorMsg . error ) . toBe ( "Connection is readonly" ) ;
380409
381410 ws1 . close ( ) ;
@@ -385,9 +414,9 @@ describe("Readonly Connections", () => {
385414 `/agents/test-readonly-agent/${ room } ?readonly=false`
386415 ) ;
387416
388- await waitForMessage (
417+ await waitForMessage < StateMessage > (
389418 ws2 ,
390- ( data : any ) => data . type === MessageType . CF_AGENT_STATE
419+ ( data ) => data . type === MessageType . CF_AGENT_STATE
391420 ) ;
392421
393422 ws2 . close ( ) ;
0 commit comments