@@ -110,6 +110,15 @@ export enum REALTIME_SUBSCRIBE_STATES {
110110
111111export const REALTIME_CHANNEL_STATES = CHANNEL_STATES
112112
113+ interface PostgresChangesFilters {
114+ postgres_changes : {
115+ id : string
116+ event : string
117+ schema ?: string
118+ table ?: string
119+ filter ?: string
120+ } [ ]
121+ }
113122/** A channel is the basic building block of Realtime
114123 * and narrows the scope of data flow to subscribed clients.
115124 * You can think of a channel as a chatroom where participants are able to see who's online
@@ -202,21 +211,23 @@ export default class RealtimeChannel {
202211
203212 /** Subscribe registers your client with the server */
204213 subscribe (
205- callback ?: ( status : `${ REALTIME_SUBSCRIBE_STATES } ` , err ?: Error ) => void ,
214+ callback ?: ( status : REALTIME_SUBSCRIBE_STATES , err ?: Error ) => void ,
206215 timeout = this . timeout
207216 ) : RealtimeChannel {
208217 if ( ! this . socket . isConnected ( ) ) {
209218 this . socket . connect ( )
210219 }
211-
212220 if ( this . joinedOnce ) {
213221 throw `tried to subscribe multiple times. 'subscribe' can only be called a single time per channel instance`
214222 } else {
215223 const {
216224 config : { broadcast, presence, private : isPrivate } ,
217225 } = this . params
218- this . _onError ( ( e : Error ) => callback && callback ( 'CHANNEL_ERROR' , e ) )
219- this . _onClose ( ( ) => callback && callback ( 'CLOSED' ) )
226+
227+ this . _onError ( ( e : Error ) =>
228+ callback ?.( REALTIME_SUBSCRIBE_STATES . CHANNEL_ERROR , e )
229+ )
230+ this . _onClose ( ( ) => callback ?.( REALTIME_SUBSCRIBE_STATES . CLOSED ) )
220231
221232 const accessTokenPayload : { access_token ?: string } = { }
222233 const config = {
@@ -227,8 +238,8 @@ export default class RealtimeChannel {
227238 private : isPrivate ,
228239 }
229240
230- if ( this . socket . accessToken ) {
231- accessTokenPayload . access_token = this . socket . accessToken
241+ if ( this . socket . accessTokenValue ) {
242+ accessTokenPayload . access_token = this . socket . accessTokenValue
232243 }
233244
234245 this . updateJoinPayload ( { ...{ config } , ...accessTokenPayload } )
@@ -237,85 +248,67 @@ export default class RealtimeChannel {
237248 this . _rejoin ( timeout )
238249
239250 this . joinPush
240- . receive (
241- 'ok' ,
242- ( {
243- postgres_changes : serverPostgresFilters ,
244- } : {
245- postgres_changes : {
246- id : string
247- event : string
248- schema ?: string
249- table ?: string
250- filter ?: string
251- } [ ]
252- } ) => {
253- this . socket . accessToken &&
254- this . socket . setAuth ( this . socket . accessToken )
255-
256- if ( serverPostgresFilters === undefined ) {
257- callback && callback ( 'SUBSCRIBED' )
258- return
259- } else {
260- const clientPostgresBindings = this . bindings . postgres_changes
261- const bindingsLen = clientPostgresBindings ?. length ?? 0
262- const newPostgresBindings = [ ]
263-
264- for ( let i = 0 ; i < bindingsLen ; i ++ ) {
265- const clientPostgresBinding = clientPostgresBindings [ i ]
266- const {
267- filter : { event, schema, table, filter } ,
268- } = clientPostgresBinding
269- const serverPostgresFilter =
270- serverPostgresFilters && serverPostgresFilters [ i ]
271-
272- if (
273- serverPostgresFilter &&
274- serverPostgresFilter . event === event &&
275- serverPostgresFilter . schema === schema &&
276- serverPostgresFilter . table === table &&
277- serverPostgresFilter . filter === filter
278- ) {
279- newPostgresBindings . push ( {
280- ...clientPostgresBinding ,
281- id : serverPostgresFilter . id ,
282- } )
283- } else {
284- this . unsubscribe ( )
285- callback &&
286- callback (
287- 'CHANNEL_ERROR' ,
288- new Error (
289- 'mismatch between server and client bindings for postgres changes'
290- )
291- )
292- return
293- }
251+ . receive ( 'ok' , async ( { postgres_changes } : PostgresChangesFilters ) => {
252+ this . socket . setAuth ( )
253+ if ( postgres_changes === undefined ) {
254+ callback ?.( REALTIME_SUBSCRIBE_STATES . SUBSCRIBED )
255+ return
256+ } else {
257+ const clientPostgresBindings = this . bindings . postgres_changes
258+ const bindingsLen = clientPostgresBindings ?. length ?? 0
259+ const newPostgresBindings = [ ]
260+
261+ for ( let i = 0 ; i < bindingsLen ; i ++ ) {
262+ const clientPostgresBinding = clientPostgresBindings [ i ]
263+ const {
264+ filter : { event, schema, table, filter } ,
265+ } = clientPostgresBinding
266+ const serverPostgresFilter =
267+ postgres_changes && postgres_changes [ i ]
268+
269+ if (
270+ serverPostgresFilter &&
271+ serverPostgresFilter . event === event &&
272+ serverPostgresFilter . schema === schema &&
273+ serverPostgresFilter . table === table &&
274+ serverPostgresFilter . filter === filter
275+ ) {
276+ newPostgresBindings . push ( {
277+ ...clientPostgresBinding ,
278+ id : serverPostgresFilter . id ,
279+ } )
280+ } else {
281+ this . unsubscribe ( )
282+ callback ?.(
283+ REALTIME_SUBSCRIBE_STATES . CHANNEL_ERROR ,
284+ new Error (
285+ 'mismatch between server and client bindings for postgres changes'
286+ )
287+ )
288+ return
294289 }
290+ }
295291
296- this . bindings . postgres_changes = newPostgresBindings
292+ this . bindings . postgres_changes = newPostgresBindings
297293
298- callback && callback ( 'SUBSCRIBED' )
299- return
300- }
294+ callback && callback ( REALTIME_SUBSCRIBE_STATES . SUBSCRIBED )
295+ return
301296 }
302- )
297+ } )
303298 . receive ( 'error' , ( error : { [ key : string ] : any } ) => {
304- callback &&
305- callback (
306- 'CHANNEL_ERROR' ,
307- new Error (
308- JSON . stringify ( Object . values ( error ) . join ( ', ' ) || 'error' )
309- )
299+ callback ?.(
300+ REALTIME_SUBSCRIBE_STATES . CHANNEL_ERROR ,
301+ new Error (
302+ JSON . stringify ( Object . values ( error ) . join ( ', ' ) || 'error' )
310303 )
304+ )
311305 return
312306 } )
313307 . receive ( 'timeout' , ( ) => {
314- callback && callback ( ' TIMED_OUT' )
308+ callback ?. ( REALTIME_SUBSCRIBE_STATES . TIMED_OUT )
315309 return
316310 } )
317311 }
318-
319312 return this
320313 }
321314
@@ -445,12 +438,13 @@ export default class RealtimeChannel {
445438 ) : Promise < RealtimeChannelSendResponse > {
446439 if ( ! this . _canPush ( ) && args . type === 'broadcast' ) {
447440 const { event, payload : endpoint_payload } = args
441+ const authorization = this . socket . accessTokenValue
442+ ? `Bearer ${ this . socket . accessTokenValue } `
443+ : ''
448444 const options = {
449445 method : 'POST' ,
450446 headers : {
451- Authorization : this . socket . accessToken
452- ? `Bearer ${ this . socket . accessToken } `
453- : '' ,
447+ Authorization : authorization ,
454448 apikey : this . socket . apiKey ? this . socket . apiKey : '' ,
455449 'Content-Type' : 'application/json' ,
456450 } ,
@@ -523,7 +517,6 @@ export default class RealtimeChannel {
523517
524518 return new Promise ( ( resolve ) => {
525519 const leavePush = new Push ( this , CHANNEL_EVENTS . leave , { } , timeout )
526-
527520 leavePush
528521 . receive ( 'ok' , ( ) => {
529522 onClose ( )
@@ -538,7 +531,6 @@ export default class RealtimeChannel {
538531 } )
539532
540533 leavePush . send ( )
541-
542534 if ( ! this . _canPush ( ) ) {
543535 leavePush . trigger ( 'ok' , { } )
544536 }
0 commit comments