1
- import type { WebSocket as WSWebSocket } from 'ws '
1
+ import WebSocket from './WebSocket '
2
2
3
3
import {
4
4
CHANNEL_EVENTS ,
@@ -17,6 +17,7 @@ import Timer from './lib/timer'
17
17
import { httpEndpointURL } from './lib/transformers'
18
18
import RealtimeChannel from './RealtimeChannel'
19
19
import type { RealtimeChannelOptions } from './RealtimeChannel'
20
+ import Push from './lib/push'
20
21
21
22
type Fetch = typeof fetch
22
23
@@ -54,7 +55,7 @@ export interface WebSocketLikeConstructor {
54
55
) : WebSocketLike
55
56
}
56
57
57
- export type WebSocketLike = WebSocket | WSWebSocket | WSWebSocketDummy
58
+ export type WebSocketLike = WebSocket | WSWebSocketDummy
58
59
59
60
export interface WebSocketLikeError {
60
61
error : any
@@ -81,17 +82,17 @@ export type RealtimeClientOptions = {
81
82
accessToken ?: ( ) => Promise < string | null >
82
83
}
83
84
84
- const NATIVE_WEBSOCKET_AVAILABLE = typeof WebSocket !== 'undefined'
85
85
const WORKER_SCRIPT = `
86
86
addEventListener("message", (e) => {
87
87
if (e.data.event === "start") {
88
88
setInterval(() => postMessage({ event: "keepAlive" }), e.data.interval);
89
89
}
90
90
});`
91
+
91
92
export default class RealtimeClient {
92
93
accessTokenValue : string | null = null
93
94
apiKey : string | null = null
94
- channels : Set < RealtimeChannel > = new Set ( )
95
+ channels : RealtimeChannel [ ] = new Array ( )
95
96
endPoint : string = ''
96
97
httpEndpoint : string = ''
97
98
headers ?: { [ key : string ] : string } = DEFAULT_HEADERS
@@ -209,33 +210,21 @@ export default class RealtimeClient {
209
210
if ( this . conn ) {
210
211
return
211
212
}
212
-
213
+ if ( ! this . transport ) {
214
+ this . transport = WebSocket
215
+ }
213
216
if ( this . transport ) {
214
217
this . conn = new this . transport ( this . endpointURL ( ) , undefined , {
215
218
headers : this . headers ,
216
219
} )
217
220
this . setupConnection ( )
218
221
return
219
222
}
220
-
221
- if ( NATIVE_WEBSOCKET_AVAILABLE ) {
222
- this . conn = new WebSocket ( this . endpointURL ( ) )
223
- this . setupConnection ( )
224
- return
225
- }
226
-
227
223
this . conn = new WSWebSocketDummy ( this . endpointURL ( ) , undefined , {
228
224
close : ( ) => {
229
225
this . conn = null
230
226
} ,
231
227
} )
232
-
233
- import ( 'ws' ) . then ( ( { default : WS } ) => {
234
- this . conn = new WS ( this . endpointURL ( ) , undefined , {
235
- headers : this . headers ,
236
- } )
237
- this . setupConnection ( )
238
- } )
239
228
}
240
229
241
230
/**
@@ -264,17 +253,19 @@ export default class RealtimeClient {
264
253
this . conn . close ( )
265
254
}
266
255
this . conn = null
256
+
267
257
// remove open handles
268
258
this . heartbeatTimer && clearInterval ( this . heartbeatTimer )
269
259
this . reconnectTimer . reset ( )
260
+ this . channels . forEach ( ( channel ) => channel . teardown ( ) )
270
261
}
271
262
}
272
263
273
264
/**
274
265
* Returns all created channels
275
266
*/
276
267
getChannels ( ) : RealtimeChannel [ ] {
277
- return Array . from ( this . channels )
268
+ return this . channels
278
269
}
279
270
280
271
/**
@@ -285,9 +276,12 @@ export default class RealtimeClient {
285
276
channel : RealtimeChannel
286
277
) : Promise < RealtimeRemoveChannelResponse > {
287
278
const status = await channel . unsubscribe ( )
288
- if ( this . channels . size === 0 ) {
279
+ this . channels = this . channels . filter ( ( c ) => c . _joinRef !== channel . _joinRef )
280
+
281
+ if ( this . channels . length === 0 ) {
289
282
this . disconnect ( )
290
283
}
284
+
291
285
return status
292
286
}
293
287
@@ -296,13 +290,10 @@ export default class RealtimeClient {
296
290
*/
297
291
async removeAllChannels ( ) : Promise < RealtimeRemoveChannelResponse [ ] > {
298
292
const values_1 = await Promise . all (
299
- Array . from ( this . channels ) . map ( ( channel ) => {
300
- this . channels . delete ( channel )
301
- return channel . unsubscribe ( )
302
- } )
293
+ this . channels . map ( ( channel ) => channel . unsubscribe ( ) )
303
294
)
295
+ this . channels = [ ]
304
296
this . disconnect ( )
305
-
306
297
return values_1
307
298
}
308
299
@@ -349,7 +340,8 @@ export default class RealtimeClient {
349
340
350
341
if ( ! exists ) {
351
342
const chan = new RealtimeChannel ( `realtime:${ topic } ` , params , this )
352
- this . channels . add ( chan )
343
+ this . channels . push ( chan )
344
+
353
345
return chan
354
346
} else {
355
347
return exists
@@ -492,7 +484,7 @@ export default class RealtimeClient {
492
484
* @internal
493
485
*/
494
486
_leaveOpenTopic ( topic : string ) : void {
495
- let dupChannel = Array . from ( this . channels ) . find (
487
+ let dupChannel = this . channels . find (
496
488
( c ) => c . topic === topic && ( c . _isJoined ( ) || c . _isJoining ( ) )
497
489
)
498
490
if ( dupChannel ) {
@@ -509,7 +501,7 @@ export default class RealtimeClient {
509
501
* @internal
510
502
*/
511
503
_remove ( channel : RealtimeChannel ) {
512
- this . channels . delete ( channel )
504
+ this . channels = this . channels . filter ( ( c ) => c . topic !== channel . topic )
513
505
}
514
506
515
507
/**
@@ -560,7 +552,7 @@ export default class RealtimeClient {
560
552
}
561
553
562
554
/** @internal */
563
- private async _onConnOpen ( ) {
555
+ private _onConnOpen ( ) {
564
556
this . log ( 'transport' , `connected to ${ this . endpointURL ( ) } ` )
565
557
this . flushSendBuffer ( )
566
558
this . reconnectTimer . reset ( )
@@ -576,11 +568,10 @@ export default class RealtimeClient {
576
568
} else {
577
569
this . log ( 'worker' , `starting default worker` )
578
570
}
579
-
580
571
const objectUrl = this . _workerObjectUrl ( this . workerUrl ! )
581
572
this . workerRef = new Worker ( objectUrl )
582
573
this . workerRef . onerror = ( error ) => {
583
- this . log ( 'worker' , 'worker error' , error . message )
574
+ this . log ( 'worker' , 'worker error' , ( error as ErrorEvent ) . message )
584
575
this . workerRef ! . terminate ( )
585
576
}
586
577
this . workerRef . onmessage = ( event ) => {
@@ -593,12 +584,10 @@ export default class RealtimeClient {
593
584
interval : this . heartbeatIntervalMs ,
594
585
} )
595
586
}
596
-
597
- this . stateChangeCallbacks . open . forEach ( ( callback ) => callback ( ) ) !
587
+ this . stateChangeCallbacks . open . forEach ( ( callback ) => callback ( ) )
598
588
}
599
589
600
590
/** @internal */
601
-
602
591
private _onConnClose ( event : any ) {
603
592
this . log ( 'transport' , 'close' , event )
604
593
this . _triggerChanError ( )
@@ -631,7 +620,6 @@ export default class RealtimeClient {
631
620
}
632
621
const prefix = url . match ( / \? / ) ? '&' : '?'
633
622
const query = new URLSearchParams ( params )
634
-
635
623
return `${ url } ${ prefix } ${ query } `
636
624
}
637
625
0 commit comments