@supabase/realtime-js 2.71.2-canary.29 → 2.71.2-canary.3

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 (89) hide show
  1. package/package.json +1 -1
  2. package/dist/main/RealtimeChannel.d.ts +0 -235
  3. package/dist/main/RealtimeChannel.d.ts.map +0 -1
  4. package/dist/main/RealtimeChannel.js +0 -576
  5. package/dist/main/RealtimeChannel.js.map +0 -1
  6. package/dist/main/RealtimeClient.d.ts +0 -196
  7. package/dist/main/RealtimeClient.d.ts.map +0 -1
  8. package/dist/main/RealtimeClient.js +0 -736
  9. package/dist/main/RealtimeClient.js.map +0 -1
  10. package/dist/main/RealtimePresence.d.ts +0 -68
  11. package/dist/main/RealtimePresence.d.ts.map +0 -1
  12. package/dist/main/RealtimePresence.js +0 -229
  13. package/dist/main/RealtimePresence.js.map +0 -1
  14. package/dist/main/index.d.ts +0 -6
  15. package/dist/main/index.d.ts.map +0 -1
  16. package/dist/main/index.js +0 -53
  17. package/dist/main/index.js.map +0 -1
  18. package/dist/main/lib/constants.d.ts +0 -37
  19. package/dist/main/lib/constants.d.ts.map +0 -1
  20. package/dist/main/lib/constants.js +0 -46
  21. package/dist/main/lib/constants.js.map +0 -1
  22. package/dist/main/lib/push.d.ts +0 -48
  23. package/dist/main/lib/push.d.ts.map +0 -1
  24. package/dist/main/lib/push.js +0 -102
  25. package/dist/main/lib/push.js.map +0 -1
  26. package/dist/main/lib/serializer.d.ts +0 -7
  27. package/dist/main/lib/serializer.d.ts.map +0 -1
  28. package/dist/main/lib/serializer.js +0 -36
  29. package/dist/main/lib/serializer.js.map +0 -1
  30. package/dist/main/lib/timer.d.ts +0 -22
  31. package/dist/main/lib/timer.d.ts.map +0 -1
  32. package/dist/main/lib/timer.js +0 -39
  33. package/dist/main/lib/timer.js.map +0 -1
  34. package/dist/main/lib/transformers.d.ts +0 -109
  35. package/dist/main/lib/transformers.d.ts.map +0 -1
  36. package/dist/main/lib/transformers.js +0 -229
  37. package/dist/main/lib/transformers.js.map +0 -1
  38. package/dist/main/lib/version.d.ts +0 -2
  39. package/dist/main/lib/version.d.ts.map +0 -1
  40. package/dist/main/lib/version.js +0 -5
  41. package/dist/main/lib/version.js.map +0 -1
  42. package/dist/main/lib/websocket-factory.d.ts +0 -35
  43. package/dist/main/lib/websocket-factory.d.ts.map +0 -1
  44. package/dist/main/lib/websocket-factory.js +0 -90
  45. package/dist/main/lib/websocket-factory.js.map +0 -1
  46. package/dist/module/RealtimeChannel.d.ts +0 -235
  47. package/dist/module/RealtimeChannel.d.ts.map +0 -1
  48. package/dist/module/RealtimeChannel.js +0 -536
  49. package/dist/module/RealtimeChannel.js.map +0 -1
  50. package/dist/module/RealtimeClient.d.ts +0 -196
  51. package/dist/module/RealtimeClient.d.ts.map +0 -1
  52. package/dist/module/RealtimeClient.js +0 -698
  53. package/dist/module/RealtimeClient.js.map +0 -1
  54. package/dist/module/RealtimePresence.d.ts +0 -68
  55. package/dist/module/RealtimePresence.d.ts.map +0 -1
  56. package/dist/module/RealtimePresence.js +0 -225
  57. package/dist/module/RealtimePresence.js.map +0 -1
  58. package/dist/module/index.d.ts +0 -6
  59. package/dist/module/index.d.ts.map +0 -1
  60. package/dist/module/index.js +0 -6
  61. package/dist/module/index.js.map +0 -1
  62. package/dist/module/lib/constants.d.ts +0 -37
  63. package/dist/module/lib/constants.d.ts.map +0 -1
  64. package/dist/module/lib/constants.js +0 -43
  65. package/dist/module/lib/constants.js.map +0 -1
  66. package/dist/module/lib/push.d.ts +0 -48
  67. package/dist/module/lib/push.d.ts.map +0 -1
  68. package/dist/module/lib/push.js +0 -99
  69. package/dist/module/lib/push.js.map +0 -1
  70. package/dist/module/lib/serializer.d.ts +0 -7
  71. package/dist/module/lib/serializer.d.ts.map +0 -1
  72. package/dist/module/lib/serializer.js +0 -33
  73. package/dist/module/lib/serializer.js.map +0 -1
  74. package/dist/module/lib/timer.d.ts +0 -22
  75. package/dist/module/lib/timer.d.ts.map +0 -1
  76. package/dist/module/lib/timer.js +0 -36
  77. package/dist/module/lib/timer.js.map +0 -1
  78. package/dist/module/lib/transformers.d.ts +0 -109
  79. package/dist/module/lib/transformers.d.ts.map +0 -1
  80. package/dist/module/lib/transformers.js +0 -217
  81. package/dist/module/lib/transformers.js.map +0 -1
  82. package/dist/module/lib/version.d.ts +0 -2
  83. package/dist/module/lib/version.d.ts.map +0 -1
  84. package/dist/module/lib/version.js +0 -2
  85. package/dist/module/lib/version.js.map +0 -1
  86. package/dist/module/lib/websocket-factory.d.ts +0 -35
  87. package/dist/module/lib/websocket-factory.d.ts.map +0 -1
  88. package/dist/module/lib/websocket-factory.js +0 -86
  89. package/dist/module/lib/websocket-factory.js.map +0 -1
@@ -1,736 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const websocket_factory_1 = __importDefault(require("./lib/websocket-factory"));
40
- const constants_1 = require("./lib/constants");
41
- const serializer_1 = __importDefault(require("./lib/serializer"));
42
- const timer_1 = __importDefault(require("./lib/timer"));
43
- const transformers_1 = require("./lib/transformers");
44
- const RealtimeChannel_1 = __importDefault(require("./RealtimeChannel"));
45
- const noop = () => { };
46
- // Connection-related constants
47
- const CONNECTION_TIMEOUTS = {
48
- HEARTBEAT_INTERVAL: 25000,
49
- RECONNECT_DELAY: 10,
50
- HEARTBEAT_TIMEOUT_FALLBACK: 100,
51
- };
52
- const RECONNECT_INTERVALS = [1000, 2000, 5000, 10000];
53
- const DEFAULT_RECONNECT_FALLBACK = 10000;
54
- const WORKER_SCRIPT = `
55
- addEventListener("message", (e) => {
56
- if (e.data.event === "start") {
57
- setInterval(() => postMessage({ event: "keepAlive" }), e.data.interval);
58
- }
59
- });`;
60
- class RealtimeClient {
61
- /**
62
- * Initializes the Socket.
63
- *
64
- * @param endPoint The string WebSocket endpoint, ie, "ws://example.com/socket", "wss://example.com", "/socket" (inherited host & protocol)
65
- * @param httpEndpoint The string HTTP endpoint, ie, "https://example.com", "/" (inherited host & protocol)
66
- * @param options.transport The Websocket Transport, for example WebSocket. This can be a custom implementation
67
- * @param options.timeout The default timeout in milliseconds to trigger push timeouts.
68
- * @param options.params The optional params to pass when connecting.
69
- * @param options.headers Deprecated: headers cannot be set on websocket connections and this option will be removed in the future.
70
- * @param options.heartbeatIntervalMs The millisec interval to send a heartbeat message.
71
- * @param options.logger The optional function for specialized logging, ie: logger: (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }
72
- * @param options.logLevel Sets the log level for Realtime
73
- * @param options.encode The function to encode outgoing messages. Defaults to JSON: (payload, callback) => callback(JSON.stringify(payload))
74
- * @param options.decode The function to decode incoming messages. Defaults to Serializer's decode.
75
- * @param options.reconnectAfterMs he optional function that returns the millsec reconnect interval. Defaults to stepped backoff off.
76
- * @param options.worker Use Web Worker to set a side flow. Defaults to false.
77
- * @param options.workerUrl The URL of the worker script. Defaults to https://realtime.supabase.com/worker.js that includes a heartbeat event call to keep the connection alive.
78
- */
79
- constructor(endPoint, options) {
80
- var _a;
81
- this.accessTokenValue = null;
82
- this.apiKey = null;
83
- this.channels = new Array();
84
- this.endPoint = '';
85
- this.httpEndpoint = '';
86
- /** @deprecated headers cannot be set on websocket connections */
87
- this.headers = {};
88
- this.params = {};
89
- this.timeout = constants_1.DEFAULT_TIMEOUT;
90
- this.transport = null;
91
- this.heartbeatIntervalMs = CONNECTION_TIMEOUTS.HEARTBEAT_INTERVAL;
92
- this.heartbeatTimer = undefined;
93
- this.pendingHeartbeatRef = null;
94
- this.heartbeatCallback = noop;
95
- this.ref = 0;
96
- this.reconnectTimer = null;
97
- this.logger = noop;
98
- this.conn = null;
99
- this.sendBuffer = [];
100
- this.serializer = new serializer_1.default();
101
- this.stateChangeCallbacks = {
102
- open: [],
103
- close: [],
104
- error: [],
105
- message: [],
106
- };
107
- this.accessToken = null;
108
- this._connectionState = 'disconnected';
109
- this._wasManualDisconnect = false;
110
- this._authPromise = null;
111
- /**
112
- * Use either custom fetch, if provided, or default fetch to make HTTP requests
113
- *
114
- * @internal
115
- */
116
- this._resolveFetch = (customFetch) => {
117
- let _fetch;
118
- if (customFetch) {
119
- _fetch = customFetch;
120
- }
121
- else if (typeof fetch === 'undefined') {
122
- // Node.js environment without native fetch
123
- _fetch = (...args) => Promise.resolve(`${'@supabase/node-fetch'}`).then(s => __importStar(require(s))).then(({ default: fetch }) => fetch(...args))
124
- .catch((error) => {
125
- throw new Error(`Failed to load @supabase/node-fetch: ${error.message}. ` +
126
- `This is required for HTTP requests in Node.js environments without native fetch.`);
127
- });
128
- }
129
- else {
130
- _fetch = fetch;
131
- }
132
- return (...args) => _fetch(...args);
133
- };
134
- // Validate required parameters
135
- if (!((_a = options === null || options === void 0 ? void 0 : options.params) === null || _a === void 0 ? void 0 : _a.apikey)) {
136
- throw new Error('API key is required to connect to Realtime');
137
- }
138
- this.apiKey = options.params.apikey;
139
- // Initialize endpoint URLs
140
- this.endPoint = `${endPoint}/${constants_1.TRANSPORTS.websocket}`;
141
- this.httpEndpoint = (0, transformers_1.httpEndpointURL)(endPoint);
142
- this._initializeOptions(options);
143
- this._setupReconnectionTimer();
144
- this.fetch = this._resolveFetch(options === null || options === void 0 ? void 0 : options.fetch);
145
- }
146
- /**
147
- * Connects the socket, unless already connected.
148
- */
149
- connect() {
150
- // Skip if already connecting, disconnecting, or connected
151
- if (this.isConnecting() ||
152
- this.isDisconnecting() ||
153
- (this.conn !== null && this.isConnected())) {
154
- return;
155
- }
156
- this._setConnectionState('connecting');
157
- this._setAuthSafely('connect');
158
- // Establish WebSocket connection
159
- if (this.transport) {
160
- // Use custom transport if provided
161
- this.conn = new this.transport(this.endpointURL());
162
- }
163
- else {
164
- // Try to use native WebSocket
165
- try {
166
- this.conn = websocket_factory_1.default.createWebSocket(this.endpointURL());
167
- }
168
- catch (error) {
169
- this._setConnectionState('disconnected');
170
- const errorMessage = error.message;
171
- // Provide helpful error message based on environment
172
- if (errorMessage.includes('Node.js')) {
173
- throw new Error(`${errorMessage}\n\n` +
174
- 'To use Realtime in Node.js, you need to provide a WebSocket implementation:\n\n' +
175
- 'Option 1: Use Node.js 22+ which has native WebSocket support\n' +
176
- 'Option 2: Install and provide the "ws" package:\n\n' +
177
- ' npm install ws\n\n' +
178
- ' import ws from "ws"\n' +
179
- ' const client = new RealtimeClient(url, {\n' +
180
- ' ...options,\n' +
181
- ' transport: ws\n' +
182
- ' })');
183
- }
184
- throw new Error(`WebSocket not available: ${errorMessage}`);
185
- }
186
- }
187
- this._setupConnectionHandlers();
188
- }
189
- /**
190
- * Returns the URL of the websocket.
191
- * @returns string The URL of the websocket.
192
- */
193
- endpointURL() {
194
- return this._appendParams(this.endPoint, Object.assign({}, this.params, { vsn: constants_1.VSN }));
195
- }
196
- /**
197
- * Disconnects the socket.
198
- *
199
- * @param code A numeric status code to send on disconnect.
200
- * @param reason A custom reason for the disconnect.
201
- */
202
- disconnect(code, reason) {
203
- if (this.isDisconnecting()) {
204
- return;
205
- }
206
- this._setConnectionState('disconnecting', true);
207
- if (this.conn) {
208
- // Setup fallback timer to prevent hanging in disconnecting state
209
- const fallbackTimer = setTimeout(() => {
210
- this._setConnectionState('disconnected');
211
- }, 100);
212
- this.conn.onclose = () => {
213
- clearTimeout(fallbackTimer);
214
- this._setConnectionState('disconnected');
215
- };
216
- // Close the WebSocket connection
217
- if (code) {
218
- this.conn.close(code, reason !== null && reason !== void 0 ? reason : '');
219
- }
220
- else {
221
- this.conn.close();
222
- }
223
- this._teardownConnection();
224
- }
225
- else {
226
- this._setConnectionState('disconnected');
227
- }
228
- }
229
- /**
230
- * Returns all created channels
231
- */
232
- getChannels() {
233
- return this.channels;
234
- }
235
- /**
236
- * Unsubscribes and removes a single channel
237
- * @param channel A RealtimeChannel instance
238
- */
239
- async removeChannel(channel) {
240
- const status = await channel.unsubscribe();
241
- if (this.channels.length === 0) {
242
- this.disconnect();
243
- }
244
- return status;
245
- }
246
- /**
247
- * Unsubscribes and removes all channels
248
- */
249
- async removeAllChannels() {
250
- const values_1 = await Promise.all(this.channels.map((channel) => channel.unsubscribe()));
251
- this.channels = [];
252
- this.disconnect();
253
- return values_1;
254
- }
255
- /**
256
- * Logs the message.
257
- *
258
- * For customized logging, `this.logger` can be overridden.
259
- */
260
- log(kind, msg, data) {
261
- this.logger(kind, msg, data);
262
- }
263
- /**
264
- * Returns the current state of the socket.
265
- */
266
- connectionState() {
267
- switch (this.conn && this.conn.readyState) {
268
- case constants_1.SOCKET_STATES.connecting:
269
- return constants_1.CONNECTION_STATE.Connecting;
270
- case constants_1.SOCKET_STATES.open:
271
- return constants_1.CONNECTION_STATE.Open;
272
- case constants_1.SOCKET_STATES.closing:
273
- return constants_1.CONNECTION_STATE.Closing;
274
- default:
275
- return constants_1.CONNECTION_STATE.Closed;
276
- }
277
- }
278
- /**
279
- * Returns `true` is the connection is open.
280
- */
281
- isConnected() {
282
- return this.connectionState() === constants_1.CONNECTION_STATE.Open;
283
- }
284
- /**
285
- * Returns `true` if the connection is currently connecting.
286
- */
287
- isConnecting() {
288
- return this._connectionState === 'connecting';
289
- }
290
- /**
291
- * Returns `true` if the connection is currently disconnecting.
292
- */
293
- isDisconnecting() {
294
- return this._connectionState === 'disconnecting';
295
- }
296
- channel(topic, params = { config: {} }) {
297
- const realtimeTopic = `realtime:${topic}`;
298
- const exists = this.getChannels().find((c) => c.topic === realtimeTopic);
299
- if (!exists) {
300
- const chan = new RealtimeChannel_1.default(`realtime:${topic}`, params, this);
301
- this.channels.push(chan);
302
- return chan;
303
- }
304
- else {
305
- return exists;
306
- }
307
- }
308
- /**
309
- * Push out a message if the socket is connected.
310
- *
311
- * If the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established.
312
- */
313
- push(data) {
314
- const { topic, event, payload, ref } = data;
315
- const callback = () => {
316
- this.encode(data, (result) => {
317
- var _a;
318
- (_a = this.conn) === null || _a === void 0 ? void 0 : _a.send(result);
319
- });
320
- };
321
- this.log('push', `${topic} ${event} (${ref})`, payload);
322
- if (this.isConnected()) {
323
- callback();
324
- }
325
- else {
326
- this.sendBuffer.push(callback);
327
- }
328
- }
329
- /**
330
- * Sets the JWT access token used for channel subscription authorization and Realtime RLS.
331
- *
332
- * If param is null it will use the `accessToken` callback function or the token set on the client.
333
- *
334
- * On callback used, it will set the value of the token internal to the client.
335
- *
336
- * @param token A JWT string to override the token set on the client.
337
- */
338
- async setAuth(token = null) {
339
- this._authPromise = this._performAuth(token);
340
- try {
341
- await this._authPromise;
342
- }
343
- finally {
344
- this._authPromise = null;
345
- }
346
- }
347
- /**
348
- * Sends a heartbeat message if the socket is connected.
349
- */
350
- async sendHeartbeat() {
351
- var _a;
352
- if (!this.isConnected()) {
353
- this.heartbeatCallback('disconnected');
354
- return;
355
- }
356
- // Handle heartbeat timeout and force reconnection if needed
357
- if (this.pendingHeartbeatRef) {
358
- this.pendingHeartbeatRef = null;
359
- this.log('transport', 'heartbeat timeout. Attempting to re-establish connection');
360
- this.heartbeatCallback('timeout');
361
- // Force reconnection after heartbeat timeout
362
- this._wasManualDisconnect = false;
363
- (_a = this.conn) === null || _a === void 0 ? void 0 : _a.close(constants_1.WS_CLOSE_NORMAL, 'heartbeat timeout');
364
- setTimeout(() => {
365
- var _a;
366
- if (!this.isConnected()) {
367
- (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.scheduleTimeout();
368
- }
369
- }, CONNECTION_TIMEOUTS.HEARTBEAT_TIMEOUT_FALLBACK);
370
- return;
371
- }
372
- // Send heartbeat message to server
373
- this.pendingHeartbeatRef = this._makeRef();
374
- this.push({
375
- topic: 'phoenix',
376
- event: 'heartbeat',
377
- payload: {},
378
- ref: this.pendingHeartbeatRef,
379
- });
380
- this.heartbeatCallback('sent');
381
- this._setAuthSafely('heartbeat');
382
- }
383
- onHeartbeat(callback) {
384
- this.heartbeatCallback = callback;
385
- }
386
- /**
387
- * Flushes send buffer
388
- */
389
- flushSendBuffer() {
390
- if (this.isConnected() && this.sendBuffer.length > 0) {
391
- this.sendBuffer.forEach((callback) => callback());
392
- this.sendBuffer = [];
393
- }
394
- }
395
- /**
396
- * Return the next message ref, accounting for overflows
397
- *
398
- * @internal
399
- */
400
- _makeRef() {
401
- let newRef = this.ref + 1;
402
- if (newRef === this.ref) {
403
- this.ref = 0;
404
- }
405
- else {
406
- this.ref = newRef;
407
- }
408
- return this.ref.toString();
409
- }
410
- /**
411
- * Unsubscribe from channels with the specified topic.
412
- *
413
- * @internal
414
- */
415
- _leaveOpenTopic(topic) {
416
- let dupChannel = this.channels.find((c) => c.topic === topic && (c._isJoined() || c._isJoining()));
417
- if (dupChannel) {
418
- this.log('transport', `leaving duplicate topic "${topic}"`);
419
- dupChannel.unsubscribe();
420
- }
421
- }
422
- /**
423
- * Removes a subscription from the socket.
424
- *
425
- * @param channel An open subscription.
426
- *
427
- * @internal
428
- */
429
- _remove(channel) {
430
- this.channels = this.channels.filter((c) => c.topic !== channel.topic);
431
- }
432
- /** @internal */
433
- _onConnMessage(rawMessage) {
434
- this.decode(rawMessage.data, (msg) => {
435
- // Handle heartbeat responses
436
- if (msg.topic === 'phoenix' && msg.event === 'phx_reply') {
437
- this.heartbeatCallback(msg.payload.status === 'ok' ? 'ok' : 'error');
438
- }
439
- // Handle pending heartbeat reference cleanup
440
- if (msg.ref && msg.ref === this.pendingHeartbeatRef) {
441
- this.pendingHeartbeatRef = null;
442
- }
443
- // Log incoming message
444
- const { topic, event, payload, ref } = msg;
445
- const refString = ref ? `(${ref})` : '';
446
- const status = payload.status || '';
447
- this.log('receive', `${status} ${topic} ${event} ${refString}`.trim(), payload);
448
- // Route message to appropriate channels
449
- this.channels
450
- .filter((channel) => channel._isMember(topic))
451
- .forEach((channel) => channel._trigger(event, payload, ref));
452
- this._triggerStateCallbacks('message', msg);
453
- });
454
- }
455
- /**
456
- * Clear specific timer
457
- * @internal
458
- */
459
- _clearTimer(timer) {
460
- var _a;
461
- if (timer === 'heartbeat' && this.heartbeatTimer) {
462
- clearInterval(this.heartbeatTimer);
463
- this.heartbeatTimer = undefined;
464
- }
465
- else if (timer === 'reconnect') {
466
- (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.reset();
467
- }
468
- }
469
- /**
470
- * Clear all timers
471
- * @internal
472
- */
473
- _clearAllTimers() {
474
- this._clearTimer('heartbeat');
475
- this._clearTimer('reconnect');
476
- }
477
- /**
478
- * Setup connection handlers for WebSocket events
479
- * @internal
480
- */
481
- _setupConnectionHandlers() {
482
- if (!this.conn)
483
- return;
484
- // Set binary type if supported (browsers and most WebSocket implementations)
485
- if ('binaryType' in this.conn) {
486
- ;
487
- this.conn.binaryType = 'arraybuffer';
488
- }
489
- this.conn.onopen = () => this._onConnOpen();
490
- this.conn.onerror = (error) => this._onConnError(error);
491
- this.conn.onmessage = (event) => this._onConnMessage(event);
492
- this.conn.onclose = (event) => this._onConnClose(event);
493
- }
494
- /**
495
- * Teardown connection and cleanup resources
496
- * @internal
497
- */
498
- _teardownConnection() {
499
- if (this.conn) {
500
- this.conn.onopen = null;
501
- this.conn.onerror = null;
502
- this.conn.onmessage = null;
503
- this.conn.onclose = null;
504
- this.conn = null;
505
- }
506
- this._clearAllTimers();
507
- this.channels.forEach((channel) => channel.teardown());
508
- }
509
- /** @internal */
510
- _onConnOpen() {
511
- this._setConnectionState('connected');
512
- this.log('transport', `connected to ${this.endpointURL()}`);
513
- this.flushSendBuffer();
514
- this._clearTimer('reconnect');
515
- if (!this.worker) {
516
- this._startHeartbeat();
517
- }
518
- else {
519
- if (!this.workerRef) {
520
- this._startWorkerHeartbeat();
521
- }
522
- }
523
- this._triggerStateCallbacks('open');
524
- }
525
- /** @internal */
526
- _startHeartbeat() {
527
- this.heartbeatTimer && clearInterval(this.heartbeatTimer);
528
- this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
529
- }
530
- /** @internal */
531
- _startWorkerHeartbeat() {
532
- if (this.workerUrl) {
533
- this.log('worker', `starting worker for from ${this.workerUrl}`);
534
- }
535
- else {
536
- this.log('worker', `starting default worker`);
537
- }
538
- const objectUrl = this._workerObjectUrl(this.workerUrl);
539
- this.workerRef = new Worker(objectUrl);
540
- this.workerRef.onerror = (error) => {
541
- this.log('worker', 'worker error', error.message);
542
- this.workerRef.terminate();
543
- };
544
- this.workerRef.onmessage = (event) => {
545
- if (event.data.event === 'keepAlive') {
546
- this.sendHeartbeat();
547
- }
548
- };
549
- this.workerRef.postMessage({
550
- event: 'start',
551
- interval: this.heartbeatIntervalMs,
552
- });
553
- }
554
- /** @internal */
555
- _onConnClose(event) {
556
- var _a;
557
- this._setConnectionState('disconnected');
558
- this.log('transport', 'close', event);
559
- this._triggerChanError();
560
- this._clearTimer('heartbeat');
561
- // Only schedule reconnection if it wasn't a manual disconnect
562
- if (!this._wasManualDisconnect) {
563
- (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.scheduleTimeout();
564
- }
565
- this._triggerStateCallbacks('close', event);
566
- }
567
- /** @internal */
568
- _onConnError(error) {
569
- this._setConnectionState('disconnected');
570
- this.log('transport', `${error}`);
571
- this._triggerChanError();
572
- this._triggerStateCallbacks('error', error);
573
- }
574
- /** @internal */
575
- _triggerChanError() {
576
- this.channels.forEach((channel) => channel._trigger(constants_1.CHANNEL_EVENTS.error));
577
- }
578
- /** @internal */
579
- _appendParams(url, params) {
580
- if (Object.keys(params).length === 0) {
581
- return url;
582
- }
583
- const prefix = url.match(/\?/) ? '&' : '?';
584
- const query = new URLSearchParams(params);
585
- return `${url}${prefix}${query}`;
586
- }
587
- _workerObjectUrl(url) {
588
- let result_url;
589
- if (url) {
590
- result_url = url;
591
- }
592
- else {
593
- const blob = new Blob([WORKER_SCRIPT], { type: 'application/javascript' });
594
- result_url = URL.createObjectURL(blob);
595
- }
596
- return result_url;
597
- }
598
- /**
599
- * Set connection state with proper state management
600
- * @internal
601
- */
602
- _setConnectionState(state, manual = false) {
603
- this._connectionState = state;
604
- if (state === 'connecting') {
605
- this._wasManualDisconnect = false;
606
- }
607
- else if (state === 'disconnecting') {
608
- this._wasManualDisconnect = manual;
609
- }
610
- }
611
- /**
612
- * Perform the actual auth operation
613
- * @internal
614
- */
615
- async _performAuth(token = null) {
616
- let tokenToSend;
617
- if (token) {
618
- tokenToSend = token;
619
- }
620
- else if (this.accessToken) {
621
- // Always call the accessToken callback to get fresh token
622
- tokenToSend = await this.accessToken();
623
- }
624
- else {
625
- tokenToSend = this.accessTokenValue;
626
- }
627
- if (this.accessTokenValue != tokenToSend) {
628
- this.accessTokenValue = tokenToSend;
629
- this.channels.forEach((channel) => {
630
- const payload = {
631
- access_token: tokenToSend,
632
- version: constants_1.DEFAULT_VERSION,
633
- };
634
- tokenToSend && channel.updateJoinPayload(payload);
635
- if (channel.joinedOnce && channel._isJoined()) {
636
- channel._push(constants_1.CHANNEL_EVENTS.access_token, {
637
- access_token: tokenToSend,
638
- });
639
- }
640
- });
641
- }
642
- }
643
- /**
644
- * Wait for any in-flight auth operations to complete
645
- * @internal
646
- */
647
- async _waitForAuthIfNeeded() {
648
- if (this._authPromise) {
649
- await this._authPromise;
650
- }
651
- }
652
- /**
653
- * Safely call setAuth with standardized error handling
654
- * @internal
655
- */
656
- _setAuthSafely(context = 'general') {
657
- this.setAuth().catch((e) => {
658
- this.log('error', `error setting auth in ${context}`, e);
659
- });
660
- }
661
- /**
662
- * Trigger state change callbacks with proper error handling
663
- * @internal
664
- */
665
- _triggerStateCallbacks(event, data) {
666
- try {
667
- this.stateChangeCallbacks[event].forEach((callback) => {
668
- try {
669
- callback(data);
670
- }
671
- catch (e) {
672
- this.log('error', `error in ${event} callback`, e);
673
- }
674
- });
675
- }
676
- catch (e) {
677
- this.log('error', `error triggering ${event} callbacks`, e);
678
- }
679
- }
680
- /**
681
- * Setup reconnection timer with proper configuration
682
- * @internal
683
- */
684
- _setupReconnectionTimer() {
685
- this.reconnectTimer = new timer_1.default(async () => {
686
- setTimeout(async () => {
687
- await this._waitForAuthIfNeeded();
688
- if (!this.isConnected()) {
689
- this.connect();
690
- }
691
- }, CONNECTION_TIMEOUTS.RECONNECT_DELAY);
692
- }, this.reconnectAfterMs);
693
- }
694
- /**
695
- * Initialize client options with defaults
696
- * @internal
697
- */
698
- _initializeOptions(options) {
699
- var _a, _b, _c, _d, _e, _f, _g, _h;
700
- // Set defaults
701
- this.transport = (_a = options === null || options === void 0 ? void 0 : options.transport) !== null && _a !== void 0 ? _a : null;
702
- this.timeout = (_b = options === null || options === void 0 ? void 0 : options.timeout) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_TIMEOUT;
703
- this.heartbeatIntervalMs =
704
- (_c = options === null || options === void 0 ? void 0 : options.heartbeatIntervalMs) !== null && _c !== void 0 ? _c : CONNECTION_TIMEOUTS.HEARTBEAT_INTERVAL;
705
- this.worker = (_d = options === null || options === void 0 ? void 0 : options.worker) !== null && _d !== void 0 ? _d : false;
706
- this.accessToken = (_e = options === null || options === void 0 ? void 0 : options.accessToken) !== null && _e !== void 0 ? _e : null;
707
- // Handle special cases
708
- if (options === null || options === void 0 ? void 0 : options.params)
709
- this.params = options.params;
710
- if (options === null || options === void 0 ? void 0 : options.logger)
711
- this.logger = options.logger;
712
- if ((options === null || options === void 0 ? void 0 : options.logLevel) || (options === null || options === void 0 ? void 0 : options.log_level)) {
713
- this.logLevel = options.logLevel || options.log_level;
714
- this.params = Object.assign(Object.assign({}, this.params), { log_level: this.logLevel });
715
- }
716
- // Set up functions with defaults
717
- this.reconnectAfterMs =
718
- (_f = options === null || options === void 0 ? void 0 : options.reconnectAfterMs) !== null && _f !== void 0 ? _f : ((tries) => {
719
- return RECONNECT_INTERVALS[tries - 1] || DEFAULT_RECONNECT_FALLBACK;
720
- });
721
- this.encode =
722
- (_g = options === null || options === void 0 ? void 0 : options.encode) !== null && _g !== void 0 ? _g : ((payload, callback) => {
723
- return callback(JSON.stringify(payload));
724
- });
725
- this.decode = (_h = options === null || options === void 0 ? void 0 : options.decode) !== null && _h !== void 0 ? _h : this.serializer.decode.bind(this.serializer);
726
- // Handle worker setup
727
- if (this.worker) {
728
- if (typeof window !== 'undefined' && !window.Worker) {
729
- throw new Error('Web Worker is not supported');
730
- }
731
- this.workerUrl = options === null || options === void 0 ? void 0 : options.workerUrl;
732
- }
733
- }
734
- }
735
- exports.default = RealtimeClient;
736
- //# sourceMappingURL=RealtimeClient.js.map