@@ -22,13 +22,13 @@ export function useCoinGeckoWebSocket({
2222 const handleMessage = useCallback ( ( event : MessageEvent ) => {
2323 const ws = wsRef . current ;
2424 const msg : WebSocketMessage = JSON . parse ( event . data ) ;
25-
25+ // Ping/Pong checking to keep connection alive as suggested in their docs
2626 if ( msg . type === 'ping' ) return ws ?. send ( JSON . stringify ( { type : 'pong' } ) ) ;
2727
2828 if ( msg . type === 'confirm_subscription' ) {
2929 const { channel } = JSON . parse ( msg ?. identifier ?? '' ) ;
3030 subscribed . current . add ( channel ) ;
31- console . log ( `Subscribed to: ${ channel } ` ) ;
31+
3232 return ;
3333 }
3434
@@ -62,44 +62,40 @@ export function useCoinGeckoWebSocket({
6262 } ) ;
6363 }
6464
65- // G3: OHLCV updates
66- if ( msg . ch === 'G3' ) {
67- setOhlcv ( ( prev ) => {
68- const lastCandle = prev [ prev . length - 1 ] ;
69-
70- const newTimeMs = msg . t ?? 0 ;
71- const newCandle : OHLCData = [
72- newTimeMs ,
73- Number ( msg . o ?? 0 ) ,
74- Number ( msg . h ?? 0 ) ,
75- Number ( msg . l ?? 0 ) ,
76- Number ( msg . c ?? 0 ) ,
77- ] ;
78-
79- // If same timestamp, update the existing candle
80- if ( lastCandle && lastCandle [ 0 ] === newTimeMs ) {
81- return [ ...prev . slice ( 0 , - 1 ) , newCandle ] ;
82- }
83-
84- // Only append if timestamp is newer than the last candle
85- if ( lastCandle && newTimeMs < lastCandle [ 0 ] ) {
86- console . warn (
87- 'Skipping out-of-order candle:' ,
88- newTimeMs ,
89- 'vs' ,
90- lastCandle [ 0 ]
91- ) ;
92- return prev ;
93- }
94-
95- // Keep all historical data + last 100 live candles
96- const historicalCount = historicalDataLength . current ;
97- const liveCandles = prev . slice ( historicalCount ) ;
98- const limitedLiveCandles = [ ...liveCandles , newCandle ] . slice ( - 100 ) ;
99-
100- return [ ...prev . slice ( 0 , historicalCount ) , ...limitedLiveCandles ] ;
101- } ) ;
65+ // G3: OHLCV updates
66+ if ( msg . ch === 'G3' ) {
67+ setOhlcv ( ( prev ) => {
68+ const newTimeMs = ( msg . t ?? 0 ) * 1000 ;
69+ console . log ( 'Received OHLCV update for time:' , newTimeMs ) ;
70+
71+ const newCandle : OHLCData = [
72+ newTimeMs ,
73+ Number ( msg . o ?? 0 ) ,
74+ Number ( msg . h ?? 0 ) ,
75+ Number ( msg . l ?? 0 ) ,
76+ Number ( msg . c ?? 0 ) ,
77+ ] ;
78+
79+ const historicalCount = historicalDataLength . current ;
80+ const historical = prev . slice ( 0 , historicalCount ) ;
81+ const live = prev . slice ( historicalCount ) ;
82+
83+ // 🔑 Upsert by timestamp
84+ const map = new Map < number , OHLCData > ( ) ;
85+ for ( const candle of live ) {
86+ map . set ( candle [ 0 ] , candle ) ;
10287 }
88+ map . set ( newTimeMs , newCandle ) ;
89+
90+ // 🔑 Sort by time ASC
91+ const updatedLive = Array . from ( map . values ( ) )
92+ . sort ( ( a , b ) => a [ 0 ] - b [ 0 ] )
93+ . slice ( - 100 ) ;
94+
95+ return [ ...historical , ...updatedLive ] ;
96+ } ) ;
97+ }
98+
10399 } , [ ] ) ;
104100
105101 // WebSocket connection setup
0 commit comments