@@ -38,14 +38,30 @@ class EventEmitter {
3838
3939export default class ChainlinkDataStreamsConsumer extends EventEmitter {
4040 constructor ( options = { } ) {
41- const { hostname, wsHostname, clientID, clientSecret, feeds } = options ;
41+ if ( 'clientID' in options ) {
42+ throw new Error (
43+ 'Deprecated: options.clientID is now options.clientId ' +
44+ 'to match capitalization of other parameters.'
45+ )
46+ }
47+ if ( 'hostname' in options ) {
48+ throw new Error (
49+ 'Deprecated: options.hostname is now options.apiUrl and requires protocol.'
50+ )
51+ }
52+ if ( 'wsHostname' in options ) {
53+ throw new Error (
54+ 'Deprecated: options.wsHostname is now options.wsUrl and requires protocol.'
55+ )
56+ }
57+ const { apiUrl, wsUrl, clientId, clientSecret, feeds } = options ;
4258 let { reconnect = { } } = options ;
4359 if ( typeof reconnect === 'boolean' ) reconnect = { enabled : reconnect } ;
4460 reconnect . enabled ??= true ;
4561 reconnect . maxAttempts ??= 1000 ;
4662 reconnect . interval ??= 100 ;
4763 super ( ) ;
48- Object . assign ( this , { hostname , wsHostname , clientID , reconnect } ) ;
64+ Object . assign ( this , { apiUrl , wsUrl , clientId , reconnect } ) ;
4965 this . setClientSecret ( clientSecret ) ;
5066 this . manuallyDisconnected = false ;
5167 this . setConnectedFeeds ( feeds ) ;
@@ -73,12 +89,12 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
7389 } ) . then ( Report . fromBulkAPIResponse ) ;
7490
7591 async fetch ( path , params = { } ) {
76- if ( ! this . hostname ) {
92+ if ( ! this . apiUrl ) {
7793 throw new Error (
7894 'Hostname was not passed to ChainlinkDataStreamsConsumer constructor.' ,
7995 ) ;
8096 }
81- const url = new URL ( path , `https:// ${ this . hostname } ` ) ;
97+ const url = new URL ( path , this . apiUrl ) ;
8298 url . search = new URLSearchParams ( params ) . toString ( ) ;
8399 const headers = this . generateHeaders ( 'GET' , path , url . search ) ;
84100 const response = await fetch ( url , { headers } ) ;
@@ -87,7 +103,7 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
87103 }
88104
89105 generateHeaders ( method , path , search , timestamp = + new Date ( ) ) {
90- if ( ! this . clientID ) {
106+ if ( ! this . clientId ) {
91107 throw new Error (
92108 'Client ID was not passed to ChainlinkDataStreamsConsumer constructor' ,
93109 ) ;
@@ -141,7 +157,7 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
141157 method ,
142158 `${ path } ${ search } ` ,
143159 base16 . encode ( sha256 . create ( ) . update ( '' ) . digest ( ) ) . toLowerCase ( ) ,
144- this . clientID ,
160+ this . clientId ,
145161 String ( timestamp ) ,
146162 ] ;
147163
@@ -161,36 +177,41 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
161177 . toLowerCase ( ) ;
162178
163179 return {
164- Authorization : this . clientID ,
180+ Authorization : this . clientId ,
165181 'X-Authorization-Timestamp' : timestamp . toString ( ) ,
166182 'X-Authorization-Signature-SHA256' : signature ,
167183 } ;
168184 }
169185
170186 connect = ( ) => {
171187 this . manuallyDisconnected = false ;
172- this . connectImpl ( )
188+ return this . connectImpl ( ) ;
173189 }
174190
175191 disconnect = ( ) => {
176192 this . manuallyDisconnected = true ;
177- this . disconnectImpl ( )
193+ return this . disconnectImpl ( ) ;
178194 }
179195
180- disconnectImpl = ( ) => {
196+ disconnectImpl = ( ) => new Promise ( ( resolve , reject ) => {
181197 const { ws } = this ;
182198 if ( ws ) {
183199 ws . off ( 'message' , this . decodeAndEmit ) ;
184200 if ( ws . readyState === WebSocket . CONNECTING ) {
185- ws . on ( 'open' , ( ) => ws . close ( ) ) ;
201+ ws . on ( 'open' , ( ) => {
202+ ws . close ( ) ;
203+ resolve ( ) ;
204+ } ) ;
186205 } else if ( ws . readyState === WebSocket . OPEN ) {
187206 ws . close ( ) ;
207+ resolve ( ) ;
188208 }
189209 this . ws = null ;
190210 } else {
191211 console . warn ( 'Already disconnected.' ) ;
212+ resolve ( ) ;
192213 }
193- } ;
214+ } ) ;
194215
195216 decodeAndEmit = ( message ) => {
196217 if ( this . listeners [ 'report' ] ) {
@@ -229,9 +250,10 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
229250 } ;
230251
231252 setConnectedFeeds = ( feeds ) => {
232- if ( ! this . wsHostname ) {
253+ console . debug ( 'Connecting to feeds:' , feeds || '[]' ) ;
254+ if ( ! this . wsUrl ) {
233255 throw new Error (
234- 'WebSocket hostname was not passed to ChainlinkDataStreamsConsumer constructor.' ,
256+ 'WebSocket URL was not passed to ChainlinkDataStreamsConsumer constructor.' ,
235257 ) ;
236258 }
237259 feeds = feeds || [ ] ;
@@ -256,81 +278,83 @@ export default class ChainlinkDataStreamsConsumer extends EventEmitter {
256278 return Promise . resolve ( )
257279 }
258280
259- connectImpl = ( ) => {
260- return new Promise ( ( resolve , reject ) => {
261- const feeds = this . feeds ;
262- if ( feeds . size < 1 ) {
263- console . debug ( 'No feeds enabled, disconnecting. Use setConnectedFeeds to connect.' )
264- if ( this . ws ) this . disconnectImpl ( ) ;
265- return resolve ( ) ;
281+ connectImpl = ( ) => new Promise ( ( resolve , reject ) => {
282+ const feeds = this . feeds ;
283+ if ( feeds . size < 1 ) {
284+ if ( this . ws ) {
285+ console . debug ( 'No feeds enabled, disconnecting. Set feeds to connect.' )
286+ this . disconnectImpl ( ) ;
287+ } else {
288+ console . debug ( 'No feeds enabled, not connecting. Set feeds to connect.' )
266289 }
267- if ( feeds . size > 0 ) {
268- const path = '/api/v1/ws' ;
269- const search = new URLSearchParams ( {
270- feedIDs : [ ...feeds ] . join ( ',' ) ,
271- } ) . toString ( ) ;
272- const url = Object . assign ( new URL ( path , `wss://${ this . wsHostname } ` ) , {
273- search,
274- } ) ;
275- const headers = this . generateHeaders ( 'GET' , path , search ) ;
276- if ( this . ws ) this . disconnectImpl ( ) ;
277- const ws = ( this . ws = new WebSocket ( url . toString ( ) , { headers } ) ) ;
278- const onerror = ( error ) => {
279- unbind ( ) ;
290+ return resolve ( ) ;
291+ }
292+ if ( feeds . size > 0 ) {
293+ const path = '/api/v1/ws' ;
294+ const search = new URLSearchParams ( {
295+ feedIDs : [ ...feeds ] . join ( ',' ) ,
296+ } ) . toString ( ) ;
297+ const url = Object . assign ( new URL ( path , this . wsUrl ) , {
298+ search,
299+ } ) ;
300+ const headers = this . generateHeaders ( 'GET' , path , search ) ;
301+ if ( this . ws ) this . disconnectImpl ( ) ;
302+ const ws = ( this . ws = new WebSocket ( url . toString ( ) , { headers } ) ) ;
303+ const onerror = ( error ) => {
304+ unbind ( ) ;
305+ resolve ( ) ;
306+ } ;
307+ const onopen = ( ) => {
308+ unbind ( ) ;
309+ // reset reconnect attempts on successful connection
310+ this . reconnect . attempts = 0 ;
311+ resolve ( this . ws ) ;
312+ } ;
313+ const unbind = ( ) => {
314+ ws . off ( 'error' , onerror ) ;
315+ ws . off ( 'open' , onopen ) ;
316+ } ;
317+ const onclose = ( ) => {
318+ unbind ( ) ;
319+ if ( ! this . reconnect ?. enabled ) {
320+ console . debug (
321+ 'Socket closed. Reconnect not enabled, will not reconnect. ' +
322+ 'Use connect() to reconnect.'
323+ ) ;
280324 resolve ( ) ;
281- } ;
282- const onopen = ( ) => {
283- unbind ( ) ;
284- // reset reconnect attempts on successful connection
285- this . reconnect . attempts = 0 ;
286- resolve ( this . ws ) ;
287- } ;
288- const unbind = ( ) => {
289- ws . off ( 'error' , onerror ) ;
290- ws . off ( 'open' , onopen ) ;
291- } ;
292- const onclose = ( ) => {
293- unbind ( ) ;
294- if ( ! this . reconnect ?. enabled ) {
295- console . debug (
296- 'Socket closed. Reconnect not enabled, will not reconnect. ' +
297- 'Use connect() to reconnect.'
298- ) ;
299- resolve ( ) ;
300- return ;
301- }
302- if ( this . manuallyDisconnected ) {
303- console . debug (
304- 'Socket closed. Manually disconnected, will not reconnect. ' +
305- 'Use connect() to reconnect.'
306- ) ;
307- resolve ( ) ;
308- return ;
309- }
310- if ( this . reconnect . attempts < this . reconnect . maxAttempts ) {
311- this . reconnect . attempts ++ ;
312- console . log (
313- `Reconnecting attempt #${ this . reconnect . attempts } /${ this . reconnect . maxAttempts } ` ,
314- `in ${ this . reconnect . interval } ms...` ,
315- ) ;
316- setTimeout ( ( ) => {
317- this . connectImpl ( ) ;
318- } , this . reconnect . interval ) ;
319- } else {
320- const error =
321- `Max reconnect attempts (${ this . reconnect . maxAttempts } ) reached. Giving up.`
322- console . error ( error ) ;
323- return reject ( new Error ( error ) )
324- }
325+ return ;
326+ }
327+ if ( this . manuallyDisconnected ) {
328+ console . debug (
329+ 'Socket closed. Manually disconnected, will not reconnect. ' +
330+ 'Use connect() to reconnect.'
331+ ) ;
325332 resolve ( ) ;
326- } ;
327- ws . on ( 'error' , onerror ) ;
328- ws . on ( 'open' , onopen ) ;
329- ws . on ( 'close' , onclose ) ;
330- ws . on ( 'message' , this . decodeAndEmit ) ;
331- }
332- } )
333- }
333+ return ;
334+ }
335+ if ( this . reconnect . attempts < this . reconnect . maxAttempts ) {
336+ this . reconnect . attempts ++ ;
337+ console . log (
338+ `Reconnecting attempt #${ this . reconnect . attempts } /${ this . reconnect . maxAttempts } ` ,
339+ `in ${ this . reconnect . interval } ms...` ,
340+ ) ;
341+ setTimeout ( ( ) => {
342+ this . connectImpl ( ) ;
343+ } , this . reconnect . interval ) ;
344+ } else {
345+ const error =
346+ `Max reconnect attempts (${ this . reconnect . maxAttempts } ) reached. Giving up.`
347+ console . error ( error ) ;
348+ return reject ( new Error ( error ) )
349+ }
350+ resolve ( ) ;
351+ } ;
352+ ws . on ( 'error' , onerror ) ;
353+ ws . on ( 'open' , onopen ) ;
354+ ws . on ( 'close' , onclose ) ;
355+ ws . on ( 'message' , this . decodeAndEmit ) ;
356+ }
357+ } )
334358}
335359
336360const compareSets = ( xs , ys ) =>
0 commit comments