@@ -17,6 +17,7 @@ import {
17
17
useState ,
18
18
} from "react" ;
19
19
import { MONOSPACE_FONT_FAMILY } from "theme/constants" ;
20
+ import type { OneWayWebSocket } from "utils/OneWayWebSocket" ;
20
21
21
22
type ItemStatus = "stale" | "valid" | "loading" ;
22
23
@@ -48,41 +49,47 @@ export const AgentMetadata: FC<AgentMetadataProps> = ({
48
49
} ) => {
49
50
const [ metadata , setMetadata ] = useState <
50
51
WorkspaceAgentMetadata [ ] | undefined
51
- > ( undefined ) ;
52
+ > ( storybookMetadata ) ;
52
53
53
54
useEffect ( ( ) => {
55
+ // Even though we're using storybookMetadata as the initial value of the
56
+ // `metadata` state, we can't sync on `metadata` itself. If we did, the
57
+ // moment we update the state with a new event, we would re-trigger the
58
+ // effect and immediately destroy the connection
54
59
if ( storybookMetadata !== undefined ) {
55
- setMetadata ( storybookMetadata ) ;
56
60
return ;
57
61
}
58
62
59
- let timeout : ReturnType < typeof setTimeout > | undefined = undefined ;
63
+ let timeoutId : number | undefined = undefined ;
64
+ let latestSocket : OneWayWebSocket | undefined = undefined ;
60
65
61
- const connect = ( ) : ( ( ) => void ) => {
62
- const source = watchAgentMetadata ( agent . id ) ;
66
+ const createNewConnection = ( ) => {
67
+ const socket = watchAgentMetadata ( agent . id ) ;
68
+ latestSocket = socket ;
63
69
64
- source . onerror = ( e ) => {
70
+ socket . addEventListener ( "error" , ( e ) => {
65
71
console . error ( "received error in watch stream" , e ) ;
66
72
setMetadata ( undefined ) ;
67
- source . close ( ) ;
73
+ socket . close ( ) ;
68
74
69
- timeout = setTimeout ( ( ) => {
70
- connect ( ) ;
71
- } , 3000 ) ;
72
- } ;
75
+ timeoutId = window . setTimeout ( ( ) => {
76
+ createNewConnection ( ) ;
77
+ } , 3_000 ) ;
78
+ } ) ;
73
79
74
- source . addEventListener ( "data" , ( e ) => {
75
- const data = JSON . parse ( e . data ) ;
76
- setMetadata ( data ) ;
80
+ socket . addEventListener ( "message" , ( e ) => {
81
+ try {
82
+ const data = JSON . parse ( e . data ) ;
83
+ setMetadata ( data ) ;
84
+ } catch ( err ) { }
77
85
} ) ;
78
- return ( ) => {
79
- if ( timeout !== undefined ) {
80
- clearTimeout ( timeout ) ;
81
- }
82
- source . close ( ) ;
83
- } ;
84
86
} ;
85
- return connect ( ) ;
87
+
88
+ createNewConnection ( ) ;
89
+ return ( ) => {
90
+ window . clearTimeout ( timeoutId ) ;
91
+ latestSocket ?. close ( ) ;
92
+ } ;
86
93
} , [ agent . id , storybookMetadata ] ) ;
87
94
88
95
if ( metadata === undefined ) {
0 commit comments