@@ -987,176 +987,181 @@ const userWebSocketApi = opts => (cb, transform) => {
987987 } )
988988}
989989
990- const marginUserWebSocketApi = opts => ( cb , transform , marginOpts = { } ) => {
991- const isTestnet = opts . testnet || ( opts . httpBase && opts . httpBase . includes ( 'testnet' ) )
992- const wsApiUrl = isTestnet
993- ? opts . wsApiTestnet || 'wss://ws-api.testnet.binance.vision/ws-api/v3'
994- : opts . wsApi || 'wss://ws-api.binance.com:443/ws-api/v3'
995-
996- const methods = httpMethods ( opts )
997- let requestId = 1
998- let renewalTimeout = null
999- let w = null
1000- let keepClosed = false
1001- const errorHandler = userErrorHandler ( cb , transform )
1002- const RENEWAL_BUFFER_MS = 5 * 60 * 1000
990+ const marginUserWebSocketApi =
991+ opts =>
992+ ( cb , transform , marginOpts = { } ) => {
993+ const isTestnet = opts . testnet || ( opts . httpBase && opts . httpBase . includes ( 'testnet' ) )
994+ const wsApiUrl = isTestnet
995+ ? opts . wsApiTestnet || 'wss://ws-api.testnet.binance.vision/ws-api/v3'
996+ : opts . wsApi || 'wss://ws-api.binance.com:443/ws-api/v3'
997+
998+ const methods = httpMethods ( opts )
999+ let requestId = 1
1000+ let renewalTimeout = null
1001+ let w = null
1002+ let keepClosed = false
1003+ const errorHandler = userErrorHandler ( cb , transform )
1004+ const RENEWAL_BUFFER_MS = 5 * 60 * 1000
1005+
1006+ const cleanup = ( options = { } , internal = false ) => {
1007+ if ( ! internal ) keepClosed = true
1008+ if ( renewalTimeout ) {
1009+ clearTimeout ( renewalTimeout )
1010+ renewalTimeout = null
1011+ }
1012+ if ( w ) {
1013+ try {
1014+ w . send (
1015+ JSONbig . stringify ( {
1016+ id : requestId ++ ,
1017+ method : 'userDataStream.unsubscribe' ,
1018+ } ) ,
1019+ )
1020+ } catch ( e ) {
1021+ // Ignore send errors during close
1022+ }
1023+ w . close ( 1000 , 'Close handle was called' , {
1024+ keepClosed : ! internal ,
1025+ ...options ,
1026+ } )
1027+ w = null
1028+ }
1029+ }
10031030
1004- const cleanup = ( options = { } , internal = false ) => {
1005- if ( ! internal ) keepClosed = true
1006- if ( renewalTimeout ) {
1007- clearTimeout ( renewalTimeout )
1008- renewalTimeout = null
1031+ const scheduleRenewal = expirationTime => {
1032+ if ( renewalTimeout ) clearTimeout ( renewalTimeout )
1033+ const delay = Math . max ( expirationTime - Date . now ( ) - RENEWAL_BUFFER_MS , 60000 )
1034+ renewalTimeout = setTimeout ( ( ) => renewToken ( ) , delay )
10091035 }
1010- if ( w ) {
1011- try {
1012- w . send (
1013- JSONbig . stringify ( {
1014- id : requestId ++ ,
1015- method : 'userDataStream.unsubscribe' ,
1016- } ) ,
1017- )
1018- } catch ( e ) {
1019- // Ignore send errors during close
1020- }
1021- w . close ( 1000 , 'Close handle was called' , {
1022- keepClosed : ! internal ,
1023- ...options ,
1024- } )
1025- w = null
1036+
1037+ const renewToken = ( ) => {
1038+ if ( keepClosed || ! w ) return
1039+ methods
1040+ . marginGetListenToken ( marginOpts )
1041+ . then ( ( { token, expirationTime } ) => {
1042+ if ( keepClosed || ! w ) return
1043+ w . send (
1044+ JSONbig . stringify ( {
1045+ id : requestId ++ ,
1046+ method : 'userDataStream.subscribe.listenToken' ,
1047+ params : { listenToken : token } ,
1048+ } ) ,
1049+ )
1050+ scheduleRenewal ( expirationTime )
1051+ } )
1052+ . catch ( err => {
1053+ if ( opts . emitStreamErrors ) errorHandler ( err )
1054+ if ( ! keepClosed ) {
1055+ renewalTimeout = setTimeout ( ( ) => renewToken ( ) , 30e3 )
1056+ }
1057+ } )
10261058 }
1027- }
10281059
1029- const scheduleRenewal = expirationTime => {
1030- if ( renewalTimeout ) clearTimeout ( renewalTimeout )
1031- const delay = Math . max ( expirationTime - Date . now ( ) - RENEWAL_BUFFER_MS , 60000 )
1032- renewalTimeout = setTimeout ( ( ) => renewToken ( ) , delay )
1033- }
1060+ const makeStream = isReconnecting => {
1061+ if ( keepClosed ) return Promise . resolve ( )
10341062
1035- const renewToken = ( ) => {
1036- if ( keepClosed || ! w ) return
1037- methods
1038- . marginGetListenToken ( marginOpts )
1039- . then ( ( { token, expirationTime } ) => {
1040- if ( keepClosed || ! w ) return
1041- w . send (
1042- JSONbig . stringify ( {
1043- id : requestId ++ ,
1044- method : 'userDataStream.subscribe.listenToken' ,
1045- params : { listenToken : token } ,
1046- } ) ,
1047- )
1048- scheduleRenewal ( expirationTime )
1049- } )
1050- . catch ( err => {
1051- if ( opts . emitStreamErrors ) errorHandler ( err )
1052- if ( ! keepClosed ) {
1053- renewalTimeout = setTimeout ( ( ) => renewToken ( ) , 30e3 )
1054- }
1055- } )
1056- }
1063+ return methods
1064+ . marginGetListenToken ( marginOpts )
1065+ . then ( ( { token, expirationTime } ) => {
1066+ if ( keepClosed ) return
10571067
1058- const makeStream = isReconnecting => {
1059- if ( keepClosed ) return Promise . resolve ( )
1060-
1061- return methods
1062- . marginGetListenToken ( marginOpts )
1063- . then ( ( { token, expirationTime } ) => {
1064- if ( keepClosed ) return
1065-
1066- w = openWebSocket ( wsApiUrl )
1067-
1068- return new Promise ( ( resolve , reject ) => {
1069- let resolved = false
1070-
1071- w . onopen = ( ) => {
1072- w . send (
1073- JSONbig . stringify ( {
1074- id : requestId ++ ,
1075- method : 'userDataStream.subscribe.listenToken' ,
1076- params : { listenToken : token } ,
1077- } ) ,
1078- )
1079- if ( opts . emitSocketOpens ) {
1080- userOpenHandler ( cb , transform ) ( )
1081- }
1082- }
1068+ w = openWebSocket ( wsApiUrl )
10831069
1084- w . onmessage = msg => {
1085- const data = JSONbig . parse ( msg . data )
1070+ return new Promise ( ( resolve , reject ) => {
1071+ let resolved = false
1072+
1073+ w . onopen = ( ) => {
1074+ w . send (
1075+ JSONbig . stringify ( {
1076+ id : requestId ++ ,
1077+ method : 'userDataStream.subscribe.listenToken' ,
1078+ params : { listenToken : token } ,
1079+ } ) ,
1080+ )
1081+ if ( opts . emitSocketOpens ) {
1082+ userOpenHandler ( cb , transform ) ( )
1083+ }
1084+ }
10861085
1087- // Control response (subscription/unsubscription)
1088- if ( 'id' in data ) {
1089- if ( data . error ) {
1090- const err = new Error ( data . error . msg || 'WebSocket API error' )
1091- err . code = data . error . code
1092- if ( ! resolved ) {
1086+ w . onmessage = msg => {
1087+ const data = JSONbig . parse ( msg . data )
1088+
1089+ // Control response (subscription/unsubscription)
1090+ if ( 'id' in data ) {
1091+ if ( data . error ) {
1092+ const err = new Error ( data . error . msg || 'WebSocket API error' )
1093+ err . code = data . error . code
1094+ if ( ! resolved ) {
1095+ resolved = true
1096+ reject ( err )
1097+ } else if ( opts . emitStreamErrors ) {
1098+ errorHandler ( err )
1099+ }
1100+ } else if ( ! resolved ) {
10931101 resolved = true
1094- reject ( err )
1095- } else if ( opts . emitStreamErrors ) {
1096- errorHandler ( err )
1102+ scheduleRenewal ( expirationTime )
1103+ resolve ( options => cleanup ( options ) )
10971104 }
1098- } else if ( ! resolved ) {
1099- resolved = true
1100- scheduleRenewal ( expirationTime )
1101- resolve ( options => cleanup ( options ) )
1105+ return
11021106 }
1103- return
1104- }
11051107
1106- // User data event - unwrap if in wrapped format
1107- let eventData = data
1108- if ( data . event && typeof data . event === 'object' ) {
1109- eventData = data . event
1110- }
1108+ // User data event - unwrap if in wrapped format
1109+ let eventData = data
1110+ if ( data . event && typeof data . event === 'object' ) {
1111+ eventData = data . event
1112+ }
11111113
1112- // Handle eventStreamTerminated - token expired
1113- if ( eventData . e === 'eventStreamTerminated' ) {
1114- cleanup ( { } , true )
1115- if ( ! keepClosed ) {
1116- setTimeout ( ( ) => makeStream ( true ) , 5e3 )
1114+ // Handle eventStreamTerminated - token expired
1115+ if ( eventData . e === 'eventStreamTerminated' ) {
1116+ cleanup ( { } , true )
1117+ if ( ! keepClosed ) {
1118+ setTimeout ( ( ) => makeStream ( true ) , 5e3 )
1119+ }
1120+ return
11171121 }
1118- return
1119- }
11201122
1121- if ( eventData . e ) {
1122- userEventHandler ( cb , transform ) ( {
1123- data : JSONbig . stringify ( eventData ) ,
1124- } )
1123+ if ( eventData . e ) {
1124+ userEventHandler (
1125+ cb ,
1126+ transform ,
1127+ ) ( {
1128+ data : JSONbig . stringify ( eventData ) ,
1129+ } )
1130+ }
11251131 }
1126- }
11271132
1128- w . onerror = event => {
1129- const error =
1130- event . error || event . message || new Error ( 'WebSocket error' )
1131- if ( opts . emitSocketErrors ) {
1132- errorHandler ( typeof error === 'string' ? new Error ( error ) : error )
1133+ w . onerror = event => {
1134+ const error =
1135+ event . error || event . message || new Error ( 'WebSocket error' )
1136+ if ( opts . emitSocketErrors ) {
1137+ errorHandler ( typeof error === 'string' ? new Error ( error ) : error )
1138+ }
11331139 }
1134- }
11351140
1136- w . onclose = ( ) => {
1137- if ( ! keepClosed && resolved ) {
1138- if ( renewalTimeout ) clearTimeout ( renewalTimeout )
1139- renewalTimeout = null
1140- w = null
1141+ w . onclose = ( ) => {
1142+ if ( ! keepClosed && resolved ) {
1143+ if ( renewalTimeout ) clearTimeout ( renewalTimeout )
1144+ renewalTimeout = null
1145+ w = null
1146+ setTimeout ( ( ) => makeStream ( true ) , 30e3 )
1147+ }
1148+ }
1149+ } )
1150+ } )
1151+ . catch ( err => {
1152+ if ( isReconnecting ) {
1153+ if ( ! keepClosed ) {
11411154 setTimeout ( ( ) => makeStream ( true ) , 30e3 )
11421155 }
1156+ if ( opts . emitStreamErrors ) errorHandler ( err )
1157+ } else {
1158+ throw err
11431159 }
11441160 } )
1145- } )
1146- . catch ( err => {
1147- if ( isReconnecting ) {
1148- if ( ! keepClosed ) {
1149- setTimeout ( ( ) => makeStream ( true ) , 30e3 )
1150- }
1151- if ( opts . emitStreamErrors ) errorHandler ( err )
1152- } else {
1153- throw err
1154- }
1155- } )
1156- }
1161+ }
11571162
1158- return makeStream ( false )
1159- }
1163+ return makeStream ( false )
1164+ }
11601165
11611166const user = ( opts , variator ) => ( cb , transform ) => {
11621167 const [ getDataStream , keepDataStream , closeDataStream ] = getStreamMethods ( opts , variator )
0 commit comments