@supabase/realtime-js 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/main/RealtimeChannel.d.ts +14 -4
  2. package/dist/main/RealtimeChannel.d.ts.map +1 -1
  3. package/dist/main/RealtimeChannel.js +29 -10
  4. package/dist/main/RealtimeChannel.js.map +1 -1
  5. package/dist/main/RealtimeClient.d.ts +29 -9
  6. package/dist/main/RealtimeClient.d.ts.map +1 -1
  7. package/dist/main/RealtimeClient.js +44 -26
  8. package/dist/main/RealtimeClient.js.map +1 -1
  9. package/dist/main/RealtimePresence.d.ts +13 -8
  10. package/dist/main/RealtimePresence.d.ts.map +1 -1
  11. package/dist/main/RealtimePresence.js +18 -15
  12. package/dist/main/RealtimePresence.js.map +1 -1
  13. package/dist/main/lib/constants.d.ts +6 -0
  14. package/dist/main/lib/constants.d.ts.map +1 -1
  15. package/dist/main/lib/constants.js +8 -1
  16. package/dist/main/lib/constants.js.map +1 -1
  17. package/dist/main/lib/version.d.ts +1 -1
  18. package/dist/main/lib/version.js +1 -1
  19. package/dist/module/RealtimeChannel.d.ts +14 -4
  20. package/dist/module/RealtimeChannel.d.ts.map +1 -1
  21. package/dist/module/RealtimeChannel.js +29 -10
  22. package/dist/module/RealtimeChannel.js.map +1 -1
  23. package/dist/module/RealtimeClient.d.ts +29 -9
  24. package/dist/module/RealtimeClient.d.ts.map +1 -1
  25. package/dist/module/RealtimeClient.js +45 -27
  26. package/dist/module/RealtimeClient.js.map +1 -1
  27. package/dist/module/RealtimePresence.d.ts +13 -8
  28. package/dist/module/RealtimePresence.d.ts.map +1 -1
  29. package/dist/module/RealtimePresence.js +18 -12
  30. package/dist/module/RealtimePresence.js.map +1 -1
  31. package/dist/module/lib/constants.d.ts +6 -0
  32. package/dist/module/lib/constants.d.ts.map +1 -1
  33. package/dist/module/lib/constants.js +7 -0
  34. package/dist/module/lib/constants.js.map +1 -1
  35. package/dist/module/lib/version.d.ts +1 -1
  36. package/dist/module/lib/version.js +1 -1
  37. package/package.json +1 -5
  38. package/src/RealtimeChannel.ts +48 -21
  39. package/src/RealtimeClient.ts +66 -34
  40. package/src/RealtimePresence.ts +19 -12
  41. package/src/lib/constants.ts +7 -0
  42. package/src/lib/version.ts +1 -1
@@ -7,6 +7,7 @@ import {
7
7
  DEFAULT_TIMEOUT,
8
8
  WS_CLOSE_NORMAL,
9
9
  DEFAULT_HEADERS,
10
+ CONNECTION_STATE,
10
11
  } from './lib/constants'
11
12
  import Timer from './lib/timer'
12
13
  import Serializer from './lib/serializer'
@@ -32,6 +33,11 @@ type Message = {
32
33
  ref: string
33
34
  }
34
35
 
36
+ type ChannelParams = {
37
+ selfBroadcast?: boolean
38
+ [key: string]: any
39
+ }
40
+
35
41
  const noop = () => {}
36
42
 
37
43
  export default class RealtimeClient {
@@ -66,9 +72,10 @@ export default class RealtimeClient {
66
72
  error: [],
67
73
  message: [],
68
74
  }
75
+ versionDate: Date | undefined = undefined
69
76
 
70
77
  /**
71
- * Initializes the Socket
78
+ * Initializes the Socket.
72
79
  *
73
80
  * @param endPoint The string WebSocket endpoint, ie, "ws://example.com/socket", "wss://example.com", "/socket" (inherited host & protocol)
74
81
  * @param options.transport The Websocket Transport, for example WebSocket.
@@ -115,14 +122,15 @@ export default class RealtimeClient {
115
122
  }
116
123
 
117
124
  /**
118
- * Connects the socket.
125
+ * Connects the socket, unless already connected.
119
126
  */
120
- connect() {
127
+ connect(): void {
121
128
  if (this.conn) {
122
129
  return
123
130
  }
124
131
 
125
132
  this.conn = new this.transport(this.endPointURL(), [], null, this.headers)
133
+
126
134
  if (this.conn) {
127
135
  // this.conn.timeout = this.longpollerTimeout // TYPE ERROR
128
136
  this.conn.binaryType = 'arraybuffer'
@@ -130,6 +138,14 @@ export default class RealtimeClient {
130
138
  this.conn.onerror = (error) => this._onConnError(error as ErrorEvent)
131
139
  this.conn.onmessage = (event) => this.onConnMessage(event)
132
140
  this.conn.onclose = (event) => this._onConnClose(event)
141
+
142
+ const versionDate = new Date(
143
+ new URL(this.conn.url).searchParams.get('vsndate') ?? ''
144
+ )
145
+
146
+ if (versionDate instanceof Date) {
147
+ this.versionDate = versionDate
148
+ }
133
149
  }
134
150
  }
135
151
 
@@ -165,7 +181,9 @@ export default class RealtimeClient {
165
181
  }
166
182
 
167
183
  /**
168
- * Logs the message. Override `this.logger` for specialized logging.
184
+ * Logs the message.
185
+ *
186
+ * For customized logging, `this.logger` can be overriden.
169
187
  */
170
188
  log(kind: string, msg: string, data?: any) {
171
189
  this.logger(kind, msg, data)
@@ -173,6 +191,7 @@ export default class RealtimeClient {
173
191
 
174
192
  /**
175
193
  * Registers a callback for connection state change event.
194
+ *
176
195
  * @param callback A function to be called when the event occurs.
177
196
  *
178
197
  * @example
@@ -183,7 +202,8 @@ export default class RealtimeClient {
183
202
  }
184
203
 
185
204
  /**
186
- * Registers a callbacks for connection state change events.
205
+ * Registers a callback for connection state change events.
206
+ *
187
207
  * @param callback A function to be called when the event occurs.
188
208
  *
189
209
  * @example
@@ -195,6 +215,7 @@ export default class RealtimeClient {
195
215
 
196
216
  /**
197
217
  * Registers a callback for connection state change events.
218
+ *
198
219
  * @param callback A function to be called when the event occurs.
199
220
  *
200
221
  * @example
@@ -206,6 +227,7 @@ export default class RealtimeClient {
206
227
 
207
228
  /**
208
229
  * Calls a function any time a message is received.
230
+ *
209
231
  * @param callback A function to be called when the event occurs.
210
232
  *
211
233
  * @example
@@ -218,24 +240,24 @@ export default class RealtimeClient {
218
240
  /**
219
241
  * Returns the current state of the socket.
220
242
  */
221
- connectionState() {
243
+ connectionState(): CONNECTION_STATE {
222
244
  switch (this.conn && this.conn.readyState) {
223
245
  case SOCKET_STATES.connecting:
224
- return 'connecting'
246
+ return CONNECTION_STATE.Connecting
225
247
  case SOCKET_STATES.open:
226
- return 'open'
248
+ return CONNECTION_STATE.Open
227
249
  case SOCKET_STATES.closing:
228
- return 'closing'
250
+ return CONNECTION_STATE.Closing
229
251
  default:
230
- return 'closed'
252
+ return CONNECTION_STATE.Closed
231
253
  }
232
254
  }
233
255
 
234
256
  /**
235
257
  * Retuns `true` is the connection is open.
236
258
  */
237
- isConnected() {
238
- return this.connectionState() === 'open'
259
+ isConnected(): boolean {
260
+ return this.connectionState() === CONNECTION_STATE.Open
239
261
  }
240
262
 
241
263
  /**
@@ -252,13 +274,16 @@ export default class RealtimeClient {
252
274
 
253
275
  channel(
254
276
  topic: string,
255
- chanParams: { [key: string]: any } = { isNewVersion: false }
256
- ) {
257
- const { isNewVersion, ...params } = chanParams
277
+ chanParams: ChannelParams = {}
278
+ ): RealtimeChannel | RealtimeSubscription {
279
+ const { selfBroadcast, ...params } = chanParams
280
+ if (selfBroadcast) {
281
+ params.self_broadcast = selfBroadcast
282
+ }
258
283
 
259
- const chan = isNewVersion
260
- ? new RealtimeChannel(topic, { ...params }, this)
261
- : new RealtimeSubscription(topic, { ...params }, this)
284
+ const chan = this.versionDate
285
+ ? new RealtimeChannel(topic, params, this)
286
+ : new RealtimeSubscription(topic, params, this)
262
287
 
263
288
  if (chan instanceof RealtimeChannel) {
264
289
  chan.presence.onJoin((key, currentPresences, newPresences) => {
@@ -288,8 +313,13 @@ export default class RealtimeClient {
288
313
  return chan
289
314
  }
290
315
 
291
- push(data: Message) {
292
- let { topic, event, payload, ref } = data
316
+ /**
317
+ * Push out a message if the socket is connected.
318
+ *
319
+ * If the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established.
320
+ */
321
+ push(data: Message): void {
322
+ const { topic, event, payload, ref } = data
293
323
  let callback = () => {
294
324
  this.encode(data, (result: any) => {
295
325
  this.conn?.send(result)
@@ -303,7 +333,7 @@ export default class RealtimeClient {
303
333
  }
304
334
  }
305
335
 
306
- onConnMessage(rawMessage: any) {
336
+ onConnMessage(rawMessage: { data: any }) {
307
337
  this.decode(rawMessage.data, (msg: Message) => {
308
338
  let { topic, event, payload, ref } = msg
309
339
 
@@ -335,7 +365,7 @@ export default class RealtimeClient {
335
365
  /**
336
366
  * Returns the URL of the websocket.
337
367
  */
338
- endPointURL() {
368
+ endPointURL(): string {
339
369
  return this._appendParams(
340
370
  this.endPoint,
341
371
  Object.assign({}, this.params, { vsn: VSN })
@@ -345,7 +375,7 @@ export default class RealtimeClient {
345
375
  /**
346
376
  * Return the next message ref, accounting for overflows
347
377
  */
348
- makeRef() {
378
+ makeRef(): string {
349
379
  let newRef = this.ref + 1
350
380
  if (newRef === this.ref) {
351
381
  this.ref = 0
@@ -364,19 +394,18 @@ export default class RealtimeClient {
364
394
  setAuth(token: string | null) {
365
395
  this.accessToken = token
366
396
 
367
- try {
368
- this.channels.forEach((channel) => {
369
- token && channel.updateJoinPayload({ user_token: token })
397
+ this.channels.forEach((channel) => {
398
+ token && channel.updateJoinPayload({ user_token: token })
370
399
 
371
- if (channel.joinedOnce && channel.isJoined()) {
372
- channel.push(CHANNEL_EVENTS.access_token, { access_token: token })
373
- }
374
- })
375
- } catch (error) {
376
- console.log('setAuth error', error)
377
- }
400
+ if (channel.joinedOnce && channel.isJoined()) {
401
+ channel.push(CHANNEL_EVENTS.access_token, { access_token: token })
402
+ }
403
+ })
378
404
  }
379
405
 
406
+ /**
407
+ * Unsubscribe from channels with the specified topic.
408
+ */
380
409
  leaveOpenTopic(topic: string): void {
381
410
  let dupChannel = this.channels.find(
382
411
  (c) => c.topic === topic && (c.isJoined() || c.isJoining())
@@ -419,7 +448,10 @@ export default class RealtimeClient {
419
448
  )
420
449
  }
421
450
 
422
- private _appendParams(url: string, params: { [key: string]: string }) {
451
+ private _appendParams(
452
+ url: string,
453
+ params: { [key: string]: string }
454
+ ): string {
423
455
  if (Object.keys(params).length === 0) {
424
456
  return url
425
457
  }
@@ -3,7 +3,6 @@
3
3
  License: https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/LICENSE.md
4
4
  */
5
5
 
6
- import cloneDeep from 'lodash.clonedeep'
7
6
  import {
8
7
  PresenceOpts,
9
8
  PresenceOnJoinCallback,
@@ -56,7 +55,8 @@ export default class RealtimePresence {
56
55
  }
57
56
 
58
57
  /**
59
- * Initializes the Presence
58
+ * Initializes the Presence.
59
+ *
60
60
  * @param channel - The RealtimeSubscription
61
61
  * @param opts - The options,
62
62
  * for example `{events: {state: 'state', diff: 'diff'}}`
@@ -112,9 +112,11 @@ export default class RealtimePresence {
112
112
  }
113
113
 
114
114
  /**
115
- * Used to sync the list of presences on the server
116
- * with the client's state. An optional `onJoin` and `onLeave` callback can
117
- * be provided to react to changes in the client's local presences across
115
+ * Used to sync the list of presences on the server with the
116
+ * client's state.
117
+ *
118
+ * An optional `onJoin` and `onLeave` callback can be provided to
119
+ * react to changes in the client's local presences across
118
120
  * disconnects and reconnects with the server.
119
121
  */
120
122
  static syncState(
@@ -123,7 +125,7 @@ export default class RealtimePresence {
123
125
  onJoin: PresenceOnJoinCallback,
124
126
  onLeave: PresenceOnLeaveCallback
125
127
  ): PresenceState {
126
- const state = cloneDeep(currentState)
128
+ const state = this.cloneDeep(currentState)
127
129
  const transformedState = this.transformState(newState)
128
130
  const joins: PresenceState = {}
129
131
  const leaves: PresenceState = {}
@@ -165,11 +167,12 @@ export default class RealtimePresence {
165
167
  }
166
168
 
167
169
  /**
170
+ * Used to sync a diff of presence join and leave events from the
171
+ * server, as they happen.
168
172
  *
169
- * Used to sync a diff of presence join and leave
170
- * events from the server, as they happen. Like `syncState`, `syncDiff`
171
- * accepts optional `onJoin` and `onLeave` callbacks to react to a user
172
- * joining or leaving from a device.
173
+ * Like `syncState`, `syncDiff` accepts optional `onJoin` and
174
+ * `onLeave` callbacks to react to a user joining or leaving from a
175
+ * device.
173
176
  */
174
177
  static syncDiff(
175
178
  state: PresenceState,
@@ -192,7 +195,7 @@ export default class RealtimePresence {
192
195
 
193
196
  this.map(joins, (key, newPresences: Presence[]) => {
194
197
  const currentPresences: Presence[] = state[key]
195
- state[key] = cloneDeep(newPresences)
198
+ state[key] = this.cloneDeep(newPresences)
196
199
 
197
200
  if (currentPresences) {
198
201
  const joinedPresenceIds = state[key].map((m: Presence) => m.presence_id)
@@ -275,7 +278,7 @@ export default class RealtimePresence {
275
278
  private static transformState(
276
279
  state: RawPresenceState | PresenceState
277
280
  ): PresenceState {
278
- state = cloneDeep(state)
281
+ state = this.cloneDeep(state)
279
282
 
280
283
  return Object.getOwnPropertyNames(state).reduce((newState, key) => {
281
284
  const presences = state[key]
@@ -297,6 +300,10 @@ export default class RealtimePresence {
297
300
  }, {} as PresenceState)
298
301
  }
299
302
 
303
+ private static cloneDeep(obj: object) {
304
+ return JSON.parse(JSON.stringify(obj))
305
+ }
306
+
300
307
  onJoin(callback: PresenceOnJoinCallback): void {
301
308
  this.caller.onJoin = callback
302
309
  }
@@ -35,3 +35,10 @@ export enum CHANNEL_EVENTS {
35
35
  export enum TRANSPORTS {
36
36
  websocket = 'websocket',
37
37
  }
38
+
39
+ export enum CONNECTION_STATE {
40
+ Connecting = 'connecting',
41
+ Open = 'open',
42
+ Closing = 'closing',
43
+ Closed = 'closed',
44
+ }
@@ -1 +1 @@
1
- export const version = '1.6.0'
1
+ export const version = '1.7.0'