@@ -19,9 +19,9 @@ type Headers = {
19
19
*/
20
20
type RealtimeResponse = {
21
21
/**
22
- * Type of the response: 'error', 'event', 'connected', or 'response'.
22
+ * Type of the response: 'error', 'event', 'connected', 'pong', or 'response'.
23
23
*/
24
- type: 'error' | 'event' | 'connected' | 'response';
24
+ type: 'error' | 'event' | 'connected' | 'response' | 'pong' ;
25
25
26
26
/**
27
27
* Data associated with the response based on the response type.
@@ -139,9 +139,14 @@ type Realtime = {
139
139
socket?: WebSocket;
140
140
141
141
/**
142
- * Timeout duration for communication operations.
142
+ * Timeout for reconnect operations.
143
143
*/
144
- timeout?: number;
144
+ timeout?: ReturnType<typeof setTimeout >;
145
+
146
+ /**
147
+ * Heartbeat interval for the realtime connection.
148
+ */
149
+ heartbeat?: ReturnType<typeof setTimeout >;
145
150
146
151
/**
147
152
* URL for establishing the WebSocket connection.
@@ -196,6 +201,11 @@ type Realtime = {
196
201
*/
197
202
createSocket: () => void;
198
203
204
+ /**
205
+ * Function to create a new heartbeat interval.
206
+ */
207
+ createHeartbeat: () => void;
208
+
199
209
/**
200
210
* Function to clean up resources associated with specified channels.
201
211
*
@@ -359,6 +369,7 @@ class Client {
359
369
private realtime: Realtime = {
360
370
socket: undefined,
361
371
timeout: undefined,
372
+ heartbeat: undefined,
362
373
url: '',
363
374
channels: new Set(),
364
375
subscriptions: new Map(),
@@ -384,6 +395,17 @@ class Client {
384
395
return 60_000;
385
396
}
386
397
},
398
+ createHeartbeat: () => {
399
+ if (this.realtime.heartbeat) {
400
+ clearTimeout(this.realtime.heartbeat);
401
+ }
402
+
403
+ this.realtime.heartbeat = window?.setInterval(() => {
404
+ this.realtime.socket?.send(JSON.stringify({
405
+ type: 'ping'
406
+ }));
407
+ }, 20_000);
408
+ },
387
409
createSocket: () => {
388
410
if (this.realtime.channels.size < 1) {
389
411
this.realtime.reconnect = false;
@@ -417,6 +439,7 @@ class Client {
417
439
this.realtime.socket.addEventListener('message', this.realtime.onMessage);
418
440
this.realtime.socket.addEventListener('open', _event => {
419
441
this.realtime.reconnectAttempts = 0;
442
+ this.realtime.createHeartbeat();
420
443
});
421
444
this.realtime.socket.addEventListener('close', event => {
422
445
if (
@@ -497,10 +520,10 @@ class Client {
497
520
498
521
/**
499
522
* Subscribes to {{spec .title | caseUcfirst }} events and passes you the payload in realtime.
500
- *
501
- * @param {string|string[]} channels
523
+ *
524
+ * @param {string|string[]} channels
502
525
* Channel to subscribe - pass a single channel as a string or multiple with an array of strings.
503
- *
526
+ *
504
527
* Possible channels are:
505
528
* - account
506
529
* - collections
@@ -628,7 +651,7 @@ class Client {
628
651
629
652
async redirect(method: string, url: URL, headers: Headers = {}, params: Payload = {}): Promise<string > {
630
653
const { uri, options } = this.prepareRequest(method, url, headers, params);
631
-
654
+
632
655
const response = await fetch(uri, {
633
656
...options,
634
657
redirect: 'manual'
0 commit comments