Skip to content

Commit 7123690

Browse files
authored
fix: soft deprecation of headers and simplify ws socket connection (#494)
starts deprecation of the headers option as now the option won't impact anything in the code version will be sent in the payload to ensure we still are able to check which version of the client lib is used
1 parent a9c0955 commit 7123690

File tree

3 files changed

+106
-56
lines changed

3 files changed

+106
-56
lines changed

src/RealtimeClient.ts

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { WebSocket } from 'isows'
33
import {
44
CHANNEL_EVENTS,
55
CONNECTION_STATE,
6-
DEFAULT_HEADERS,
6+
DEFAULT_VERSION,
77
DEFAULT_TIMEOUT,
88
SOCKET_STATES,
99
TRANSPORTS,
@@ -44,13 +44,12 @@ export type HeartbeatStatus =
4444
| 'timeout'
4545
| 'disconnected'
4646

47-
const noop = () => { }
47+
const noop = () => {}
4848

4949
export interface WebSocketLikeConstructor {
50-
new(
50+
new (
5151
address: string | URL,
52-
_ignored?: any,
53-
options?: { headers: Object | undefined }
52+
subprotocols?: string | string[] | undefined
5453
): WebSocketLike
5554
}
5655

@@ -94,7 +93,8 @@ export default class RealtimeClient {
9493
channels: RealtimeChannel[] = new Array()
9594
endPoint: string = ''
9695
httpEndpoint: string = ''
97-
headers?: { [key: string]: string } = DEFAULT_HEADERS
96+
/** @deprecated headers cannot be set on websocket connections */
97+
headers?: { [key: string]: string } = {}
9898
params?: { [key: string]: string } = {}
9999
timeout: number = DEFAULT_TIMEOUT
100100
transport: WebSocketLikeConstructor | null
@@ -118,11 +118,11 @@ export default class RealtimeClient {
118118
error: Function[]
119119
message: Function[]
120120
} = {
121-
open: [],
122-
close: [],
123-
error: [],
124-
message: [],
125-
}
121+
open: [],
122+
close: [],
123+
error: [],
124+
message: [],
125+
}
126126
fetch: Fetch
127127
accessToken: (() => Promise<string | null>) | null = null
128128
worker?: boolean
@@ -137,7 +137,7 @@ export default class RealtimeClient {
137137
* @param options.transport The Websocket Transport, for example WebSocket. This can be a custom implementation
138138
* @param options.timeout The default timeout in milliseconds to trigger push timeouts.
139139
* @param options.params The optional params to pass when connecting.
140-
* @param options.headers The optional headers to pass when connecting.
140+
* @param options.headers Deprecated: headers cannot be set on websocket connections and this option will be removed in the future.
141141
* @param options.heartbeatIntervalMs The millisec interval to send a heartbeat message.
142142
* @param options.logger The optional function for specialized logging, ie: logger: (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }
143143
* @param options.logLevel Sets the log level for Realtime
@@ -156,7 +156,6 @@ export default class RealtimeClient {
156156
this.transport = null
157157
}
158158
if (options?.params) this.params = options.params
159-
if (options?.headers) this.headers = { ...this.headers, ...options.headers }
160159
if (options?.timeout) this.timeout = options.timeout
161160
if (options?.logger) this.logger = options.logger
162161
if (options?.logLevel || options?.log_level) {
@@ -176,13 +175,13 @@ export default class RealtimeClient {
176175
this.reconnectAfterMs = options?.reconnectAfterMs
177176
? options.reconnectAfterMs
178177
: (tries: number) => {
179-
return [1000, 2000, 5000, 10000][tries - 1] || 10000
180-
}
178+
return [1000, 2000, 5000, 10000][tries - 1] || 10000
179+
}
181180
this.encode = options?.encode
182181
? options.encode
183182
: (payload: JSON, callback: Function) => {
184-
return callback(JSON.stringify(payload))
185-
}
183+
return callback(JSON.stringify(payload))
184+
}
186185
this.decode = options?.decode
187186
? options.decode
188187
: this.serializer.decode.bind(this.serializer)
@@ -212,10 +211,10 @@ export default class RealtimeClient {
212211
if (!this.transport) {
213212
this.transport = WebSocket
214213
}
215-
216-
this.conn = new this.transport(this.endpointURL(), undefined, {
217-
headers: this.headers,
218-
}) as WebSocketLike
214+
if (!this.transport) {
215+
throw new Error('No transport provided')
216+
}
217+
this.conn = new this.transport(this.endpointURL()) as WebSocketLike
219218
this.setupConnection()
220219
}
221220

@@ -238,7 +237,7 @@ export default class RealtimeClient {
238237
*/
239238
disconnect(code?: number, reason?: string): void {
240239
if (this.conn) {
241-
this.conn.onclose = function () { } // noop
240+
this.conn.onclose = function () {} // noop
242241
if (code) {
243242
this.conn.close(code, reason ?? '')
244243
} else {
@@ -377,11 +376,12 @@ export default class RealtimeClient {
377376
if (this.accessTokenValue != tokenToSend) {
378377
this.accessTokenValue = tokenToSend
379378
this.channels.forEach((channel) => {
380-
tokenToSend &&
381-
channel.updateJoinPayload({
382-
access_token: tokenToSend,
383-
version: this.headers && this.headers['X-Client-Info'],
384-
})
379+
const payload = {
380+
access_token: tokenToSend,
381+
version: DEFAULT_VERSION,
382+
}
383+
384+
tokenToSend && channel.updateJoinPayload(payload)
385385

386386
if (channel.joinedOnce && channel._isJoined()) {
387387
channel._push(CHANNEL_EVENTS.access_token, {
@@ -525,7 +525,8 @@ export default class RealtimeClient {
525525

526526
this.log(
527527
'receive',
528-
`${payload.status || ''} ${topic} ${event} ${(ref && '(' + ref + ')') || ''
528+
`${payload.status || ''} ${topic} ${event} ${
529+
(ref && '(' + ref + ')') || ''
529530
}`,
530531
payload
531532
)
@@ -633,4 +634,4 @@ export default class RealtimeClient {
633634
}
634635
return result_url
635636
}
636-
}
637+
}

src/lib/constants.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { version } from './version'
22

3-
export const DEFAULT_HEADERS = { 'X-Client-Info': `realtime-js/${version}` }
4-
3+
export const DEFAULT_VERSION = `realtime-js/${version}`
54
export const VSN: string = '1.0.0'
65

76
export const VERSION = version

test/RealtimeClient.test.ts

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import sinon from 'sinon'
1515
import crypto from 'crypto'
1616
import RealtimeClient, { HeartbeatStatus } from '../src/RealtimeClient'
1717
import jwt from 'jsonwebtoken'
18-
import { CHANNEL_STATES } from '../src/lib/constants'
18+
import { CHANNEL_STATES, DEFAULT_VERSION } from '../src/lib/constants'
1919
import path from 'path'
2020

2121
function generateJWT(exp: string): string {
@@ -31,17 +31,12 @@ let randomProjectRef = () => crypto.randomUUID()
3131
let mockServer: Server
3232
let projectRef: string
3333
let url: string
34-
const version = crypto.randomUUID()
34+
3535
beforeEach(() => {
3636
projectRef = randomProjectRef()
3737
url = `wss://${projectRef}/socket`
3838
mockServer = new Server(url)
39-
socket = new RealtimeClient(url, {
40-
transport: MockWebSocket,
41-
headers: {
42-
'X-Client-Info': version,
43-
},
44-
})
39+
socket = new RealtimeClient(url, { transport: MockWebSocket })
4540
})
4641

4742
afterEach(() => {
@@ -71,8 +66,8 @@ describe('constructor', () => {
7166
})
7267

7368
test('overrides some defaults with options', () => {
74-
const customLogger = function logger() { }
75-
const customReconnect = function reconnect() { }
69+
const customLogger = function logger() {}
70+
const customReconnect = function reconnect() {}
7671

7772
socket = new RealtimeClient(`wss://${projectRef}/socket`, {
7873
timeout: 40000,
@@ -456,9 +451,15 @@ describe('setAuth', () => {
456451
assert.ok(!pushStub2.calledWith('access_token', { access_token: token }))
457452
assert.ok(pushStub3.calledWith('access_token', { access_token: token }))
458453

459-
assert.ok(payloadStub1.calledWith({ access_token: token, version }))
460-
assert.ok(payloadStub2.calledWith({ access_token: token, version }))
461-
assert.ok(payloadStub3.calledWith({ access_token: token, version }))
454+
assert.ok(
455+
payloadStub1.calledWith({ access_token: token, version: DEFAULT_VERSION })
456+
)
457+
assert.ok(
458+
payloadStub2.calledWith({ access_token: token, version: DEFAULT_VERSION })
459+
)
460+
assert.ok(
461+
payloadStub3.calledWith({ access_token: token, version: DEFAULT_VERSION })
462+
)
462463
})
463464

464465
test("does not send message if token hasn't changed", async () => {
@@ -477,7 +478,12 @@ describe('setAuth', () => {
477478
await socket.setAuth(token)
478479

479480
assert.strictEqual(socket.accessTokenValue, token)
480-
assert.ok(payloadStub1.calledOnceWith({ access_token: token, version }))
481+
assert.ok(
482+
payloadStub1.calledOnceWith({
483+
access_token: token,
484+
version: DEFAULT_VERSION,
485+
})
486+
)
481487
})
482488

483489
test("sets access token, updates channels' join payload, and pushes token to channels if is not a jwt", async () => {
@@ -510,16 +516,30 @@ describe('setAuth', () => {
510516
!pushStub2.calledWith('access_token', { access_token: new_token })
511517
)
512518
assert.ok(pushStub3.calledWith('access_token', { access_token: new_token }))
513-
assert.ok(payloadStub1.calledWith({ access_token: new_token, version }))
514-
assert.ok(payloadStub2.calledWith({ access_token: new_token, version }))
515-
assert.ok(payloadStub3.calledWith({ access_token: new_token, version }))
519+
assert.ok(
520+
payloadStub1.calledWith({
521+
access_token: new_token,
522+
version: DEFAULT_VERSION,
523+
})
524+
)
525+
assert.ok(
526+
payloadStub2.calledWith({
527+
access_token: new_token,
528+
version: DEFAULT_VERSION,
529+
})
530+
)
531+
assert.ok(
532+
payloadStub3.calledWith({
533+
access_token: new_token,
534+
version: DEFAULT_VERSION,
535+
})
536+
)
516537
})
517538

518539
test("sets access token using callback, updates channels' join payload, and pushes token to channels", async () => {
519540
let new_token = generateJWT('1h')
520541
let new_socket = new RealtimeClient(url, {
521542
transport: MockWebSocket,
522-
headers: { 'X-Client-Info': version },
523543
accessToken: () => Promise.resolve(token),
524544
})
525545

@@ -551,9 +571,24 @@ describe('setAuth', () => {
551571
!pushStub2.calledWith('access_token', { access_token: new_token })
552572
)
553573
assert.ok(pushStub3.calledWith('access_token', { access_token: new_token }))
554-
assert.ok(payloadStub1.calledWith({ access_token: new_token, version }))
555-
assert.ok(payloadStub2.calledWith({ access_token: new_token, version }))
556-
assert.ok(payloadStub3.calledWith({ access_token: new_token, version }))
574+
assert.ok(
575+
payloadStub1.calledWith({
576+
access_token: new_token,
577+
version: DEFAULT_VERSION,
578+
})
579+
)
580+
assert.ok(
581+
payloadStub2.calledWith({
582+
access_token: new_token,
583+
version: DEFAULT_VERSION,
584+
})
585+
)
586+
assert.ok(
587+
payloadStub3.calledWith({
588+
access_token: new_token,
589+
version: DEFAULT_VERSION,
590+
})
591+
)
557592
})
558593

559594
test("overrides access token, updates channels' join payload, and pushes token to channels", () => {
@@ -585,9 +620,24 @@ describe('setAuth', () => {
585620
!pushStub2.calledWith('access_token', { access_token: new_token })
586621
)
587622
assert.ok(pushStub3.calledWith('access_token', { access_token: new_token }))
588-
assert.ok(payloadStub1.calledWith({ access_token: new_token, version }))
589-
assert.ok(payloadStub2.calledWith({ access_token: new_token, version }))
590-
assert.ok(payloadStub3.calledWith({ access_token: new_token, version }))
623+
assert.ok(
624+
payloadStub1.calledWith({
625+
access_token: new_token,
626+
version: DEFAULT_VERSION,
627+
})
628+
)
629+
assert.ok(
630+
payloadStub2.calledWith({
631+
access_token: new_token,
632+
version: DEFAULT_VERSION,
633+
})
634+
)
635+
assert.ok(
636+
payloadStub3.calledWith({
637+
access_token: new_token,
638+
version: DEFAULT_VERSION,
639+
})
640+
)
591641
})
592642
})
593643

@@ -667,7 +717,7 @@ describe('flushSendBuffer', () => {
667717

668718
test('empties sendBuffer', () => {
669719
vi.spyOn(socket.conn!, 'readyState', 'get').mockReturnValue(1) // open
670-
socket.sendBuffer.push(() => { })
720+
socket.sendBuffer.push(() => {})
671721

672722
socket.flushSendBuffer()
673723

0 commit comments

Comments
 (0)