@@ -12,26 +12,64 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
1212 const server = useServer ( )
1313 const abort = new AbortController ( )
1414
15- const eventSdk = createOpencodeClient ( {
16- baseUrl : server . url ,
17- signal : abort . signal ,
18- fetch : platform . fetch ,
19- } )
2015 const emitter = createGlobalEmitter < {
2116 [ key : string ] : Event
2217 } > ( )
2318
24- void ( async ( ) => {
25- const events = await eventSdk . global . event ( )
26- for await ( const event of events . stream ) {
27- emitter . emit ( event . directory ?? "global" , event . payload )
19+ let currentStreamAbort : AbortController | null = null
20+
21+ async function connectEventStream ( ) {
22+ if ( currentStreamAbort ) {
23+ currentStreamAbort . abort ( )
24+ }
25+
26+ currentStreamAbort = new AbortController ( )
27+ const streamAbort = currentStreamAbort
28+
29+ const eventSdk = createOpencodeClient ( {
30+ baseUrl : server . url ,
31+ signal : streamAbort . signal ,
32+ fetch : platform . fetch ,
33+ } )
34+
35+ try {
36+ const events = await eventSdk . global . event ( )
37+ for await ( const event of events . stream ) {
38+ if ( streamAbort . signal . aborted ) break
39+ emitter . emit ( event . directory ?? "global" , event . payload )
40+ }
41+ } catch ( error : any ) {
42+ if ( error . name === "AbortError" || streamAbort . signal . aborted ) return
43+ console . error ( "Event stream error:" , error )
2844 }
29- } ) ( ) . catch ( ( error ) => {
30- if ( error . name === "AbortError" ) return
31- console . error ( "Event stream error:" , error )
32- } )
3345
34- onCleanup ( ( ) => abort . abort ( ) )
46+ if ( ! abort . signal . aborted && ! streamAbort . signal . aborted ) {
47+ setTimeout ( ( ) => {
48+ if ( ! abort . signal . aborted ) {
49+ connectEventStream ( )
50+ }
51+ } , 1000 )
52+ }
53+ }
54+
55+ connectEventStream ( )
56+
57+ // Reconnect when tab regains visibility - browsers kill background SSE connections
58+ function handleVisibilityChange ( ) {
59+ if ( document . visibilityState === "visible" && ! abort . signal . aborted ) {
60+ connectEventStream ( )
61+ }
62+ }
63+
64+ document . addEventListener ( "visibilitychange" , handleVisibilityChange )
65+
66+ onCleanup ( ( ) => {
67+ abort . abort ( )
68+ if ( currentStreamAbort ) {
69+ currentStreamAbort . abort ( )
70+ }
71+ document . removeEventListener ( "visibilitychange" , handleVisibilityChange )
72+ } )
3573
3674 const sdk = createOpencodeClient ( {
3775 baseUrl : server . url ,
0 commit comments