mezon-js 2.13.61 → 2.13.62

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.
@@ -57,6 +57,7 @@ __export(index_exports, {
57
57
  ChannelStreamMode: () => ChannelStreamMode,
58
58
  ChannelType: () => ChannelType,
59
59
  Client: () => Client,
60
+ ConnectionState: () => ConnectionState,
60
61
  DefaultSocket: () => DefaultSocket,
61
62
  NotificationType: () => NotificationType,
62
63
  Session: () => Session,
@@ -7469,6 +7470,12 @@ function CreateChannelMessageFromEvent(message) {
7469
7470
  };
7470
7471
  return e;
7471
7472
  }
7473
+ var __hasConnectedOnce = false;
7474
+ var ConnectionState = {
7475
+ DISCONNECTED: "disconnected",
7476
+ CONNECTING: "connecting",
7477
+ CONNECTED: "connected"
7478
+ };
7472
7479
  var _DefaultSocket = class _DefaultSocket {
7473
7480
  constructor(host, port, useSSL = false, verbose = false, adapter = new WebSocketAdapterText(), sendTimeoutMs = _DefaultSocket.DefaultSendTimeoutMs) {
7474
7481
  this.host = host;
@@ -7480,7 +7487,7 @@ var _DefaultSocket = class _DefaultSocket {
7480
7487
  this.cIds = {};
7481
7488
  this.nextCid = 1;
7482
7489
  this._heartbeatTimeoutMs = _DefaultSocket.DefaultHeartbeatTimeoutMs;
7483
- this.hasConnectedBefore = false;
7490
+ this._connectionState = ConnectionState.DISCONNECTED;
7484
7491
  }
7485
7492
  generatecid() {
7486
7493
  const cid = this.nextCid.toString();
@@ -7488,12 +7495,17 @@ var _DefaultSocket = class _DefaultSocket {
7488
7495
  return cid;
7489
7496
  }
7490
7497
  isOpen() {
7491
- return this.adapter.isOpen();
7498
+ return this._connectionState === ConnectionState.CONNECTED;
7492
7499
  }
7493
7500
  connect(session, createStatus = false, platform = "", connectTimeoutMs = _DefaultSocket.DefaultConnectTimeoutMs, signal) {
7494
- if (this.adapter.isOpen()) {
7501
+ if (this._connectionState === ConnectionState.CONNECTED) {
7495
7502
  return Promise.resolve(session);
7496
7503
  }
7504
+ if (this._connectionState === ConnectionState.CONNECTING && this._connectPromise) {
7505
+ return this._connectPromise;
7506
+ }
7507
+ this.clearConnectTimeout();
7508
+ this._connectionState = ConnectionState.CONNECTING;
7497
7509
  const scheme = this.useSSL ? "wss://" : "ws://";
7498
7510
  this.adapter.connect(
7499
7511
  scheme,
@@ -7505,11 +7517,11 @@ var _DefaultSocket = class _DefaultSocket {
7505
7517
  signal
7506
7518
  );
7507
7519
  this.adapter.onClose = (evt) => {
7520
+ this._connectionState = ConnectionState.DISCONNECTED;
7521
+ this.stopHeartbeatLoop();
7522
+ this.clearConnectTimeout();
7508
7523
  this.ondisconnect(evt);
7509
7524
  };
7510
- this.adapter.onError = (evt) => {
7511
- this.onerror(evt);
7512
- };
7513
7525
  this.adapter.onMessage = (message) => __async(this, null, function* () {
7514
7526
  if (this.verbose && window && window.console) {
7515
7527
  console.log("Response: %o", JSON.stringify(message));
@@ -7714,29 +7726,46 @@ var _DefaultSocket = class _DefaultSocket {
7714
7726
  }
7715
7727
  }
7716
7728
  });
7717
- return new Promise((resolve, reject) => {
7729
+ const connectPromise = new Promise((resolve, reject) => {
7718
7730
  this.adapter.onOpen = (evt) => {
7719
7731
  if (this.verbose && window && window.console) {
7720
7732
  console.log(evt);
7721
7733
  }
7722
- const isReconnect = this.hasConnectedBefore;
7723
- this.hasConnectedBefore = true;
7724
- this.pingPong();
7734
+ const isReconnect = __hasConnectedOnce;
7735
+ __hasConnectedOnce = true;
7736
+ this.clearConnectTimeout();
7737
+ this._connectionState = ConnectionState.CONNECTED;
7738
+ this.startHeartbeatLoop();
7739
+ this._connectPromise = void 0;
7725
7740
  resolve(session);
7726
7741
  if (isReconnect) {
7727
7742
  this.onreconnect(evt);
7728
7743
  }
7729
7744
  };
7730
7745
  this.adapter.onError = (evt) => {
7731
- reject(evt);
7746
+ this._connectionState = ConnectionState.DISCONNECTED;
7747
+ this.stopHeartbeatLoop();
7748
+ this.clearConnectTimeout();
7749
+ this.onerror(evt);
7750
+ this._connectPromise = void 0;
7732
7751
  this.adapter.close();
7752
+ reject(evt);
7733
7753
  };
7734
- setTimeout(() => {
7754
+ this._connectTimeoutTimer = setTimeout(() => {
7755
+ this._connectionState = ConnectionState.DISCONNECTED;
7756
+ this.stopHeartbeatLoop();
7757
+ this.adapter.close();
7758
+ this._connectPromise = void 0;
7735
7759
  reject("The socket timed out when trying to connect.");
7760
+ this._connectTimeoutTimer = void 0;
7736
7761
  }, connectTimeoutMs);
7737
7762
  });
7763
+ this._connectPromise = connectPromise;
7764
+ return this._connectPromise;
7738
7765
  }
7739
7766
  disconnect(fireDisconnectEvent = true) {
7767
+ this._connectionState = ConnectionState.DISCONNECTED;
7768
+ this.stopHeartbeatLoop();
7740
7769
  if (this.adapter.isOpen()) {
7741
7770
  this.adapter.close();
7742
7771
  }
@@ -7761,6 +7790,8 @@ var _DefaultSocket = class _DefaultSocket {
7761
7790
  }
7762
7791
  }
7763
7792
  onerror(evt) {
7793
+ this._connectionState = ConnectionState.DISCONNECTED;
7794
+ this.stopHeartbeatLoop();
7764
7795
  if (this.verbose && window && window.console) {
7765
7796
  console.log(evt);
7766
7797
  }
@@ -8131,9 +8162,11 @@ var _DefaultSocket = class _DefaultSocket {
8131
8162
  }
8132
8163
  const cid = this.generatecid();
8133
8164
  this.cIds[cid] = { resolve, reject };
8134
- setTimeout(() => {
8135
- reject("The socket timed out while waiting for a response.");
8136
- }, sendTimeout);
8165
+ if (sendTimeout !== Infinity && sendTimeout > 0) {
8166
+ setTimeout(() => {
8167
+ reject("The socket timed out while waiting for a response.");
8168
+ }, sendTimeout);
8169
+ }
8137
8170
  untypedMessage.cid = cid;
8138
8171
  this.adapter.send(untypedMessage);
8139
8172
  }
@@ -8326,7 +8359,7 @@ var _DefaultSocket = class _DefaultSocket {
8326
8359
  code,
8327
8360
  topic_id
8328
8361
  }
8329
- });
8362
+ }, Infinity);
8330
8363
  return response.channel_message_ack;
8331
8364
  });
8332
8365
  }
@@ -8531,12 +8564,16 @@ var _DefaultSocket = class _DefaultSocket {
8531
8564
  }
8532
8565
  pingPong() {
8533
8566
  return __async(this, null, function* () {
8534
- if (!this.adapter.isOpen()) {
8567
+ if (!this.isOpen()) {
8568
+ this._connectionState = ConnectionState.DISCONNECTED;
8569
+ this.stopHeartbeatLoop();
8535
8570
  return;
8536
8571
  }
8537
8572
  try {
8538
8573
  yield this.send({ ping: {} }, this._heartbeatTimeoutMs);
8539
8574
  } catch (e) {
8575
+ this._connectionState = ConnectionState.DISCONNECTED;
8576
+ this.stopHeartbeatLoop();
8540
8577
  if (this.adapter.isOpen()) {
8541
8578
  if (window && window.console) {
8542
8579
  console.error("Server unreachable from heartbeat.");
@@ -8546,9 +8583,28 @@ var _DefaultSocket = class _DefaultSocket {
8546
8583
  }
8547
8584
  return;
8548
8585
  }
8549
- setTimeout(() => this.pingPong(), this._heartbeatTimeoutMs);
8586
+ this.startHeartbeatLoop();
8550
8587
  });
8551
8588
  }
8589
+ startHeartbeatLoop() {
8590
+ this.stopHeartbeatLoop();
8591
+ this._heartbeatTimer = setTimeout(
8592
+ () => this.pingPong(),
8593
+ this._heartbeatTimeoutMs
8594
+ );
8595
+ }
8596
+ stopHeartbeatLoop() {
8597
+ if (this._heartbeatTimer !== void 0) {
8598
+ clearTimeout(this._heartbeatTimer);
8599
+ this._heartbeatTimer = void 0;
8600
+ }
8601
+ }
8602
+ clearConnectTimeout() {
8603
+ if (this._connectTimeoutTimer !== void 0) {
8604
+ clearTimeout(this._connectTimeoutTimer);
8605
+ this._connectTimeoutTimer = void 0;
8606
+ }
8607
+ }
8552
8608
  };
8553
8609
  _DefaultSocket.DefaultHeartbeatTimeoutMs = 1e4;
8554
8610
  _DefaultSocket.DefaultSendTimeoutMs = 1e4;
@@ -7435,6 +7435,12 @@ function CreateChannelMessageFromEvent(message) {
7435
7435
  };
7436
7436
  return e;
7437
7437
  }
7438
+ var __hasConnectedOnce = false;
7439
+ var ConnectionState = {
7440
+ DISCONNECTED: "disconnected",
7441
+ CONNECTING: "connecting",
7442
+ CONNECTED: "connected"
7443
+ };
7438
7444
  var _DefaultSocket = class _DefaultSocket {
7439
7445
  constructor(host, port, useSSL = false, verbose = false, adapter = new WebSocketAdapterText(), sendTimeoutMs = _DefaultSocket.DefaultSendTimeoutMs) {
7440
7446
  this.host = host;
@@ -7446,7 +7452,7 @@ var _DefaultSocket = class _DefaultSocket {
7446
7452
  this.cIds = {};
7447
7453
  this.nextCid = 1;
7448
7454
  this._heartbeatTimeoutMs = _DefaultSocket.DefaultHeartbeatTimeoutMs;
7449
- this.hasConnectedBefore = false;
7455
+ this._connectionState = ConnectionState.DISCONNECTED;
7450
7456
  }
7451
7457
  generatecid() {
7452
7458
  const cid = this.nextCid.toString();
@@ -7454,12 +7460,17 @@ var _DefaultSocket = class _DefaultSocket {
7454
7460
  return cid;
7455
7461
  }
7456
7462
  isOpen() {
7457
- return this.adapter.isOpen();
7463
+ return this._connectionState === ConnectionState.CONNECTED;
7458
7464
  }
7459
7465
  connect(session, createStatus = false, platform = "", connectTimeoutMs = _DefaultSocket.DefaultConnectTimeoutMs, signal) {
7460
- if (this.adapter.isOpen()) {
7466
+ if (this._connectionState === ConnectionState.CONNECTED) {
7461
7467
  return Promise.resolve(session);
7462
7468
  }
7469
+ if (this._connectionState === ConnectionState.CONNECTING && this._connectPromise) {
7470
+ return this._connectPromise;
7471
+ }
7472
+ this.clearConnectTimeout();
7473
+ this._connectionState = ConnectionState.CONNECTING;
7463
7474
  const scheme = this.useSSL ? "wss://" : "ws://";
7464
7475
  this.adapter.connect(
7465
7476
  scheme,
@@ -7471,11 +7482,11 @@ var _DefaultSocket = class _DefaultSocket {
7471
7482
  signal
7472
7483
  );
7473
7484
  this.adapter.onClose = (evt) => {
7485
+ this._connectionState = ConnectionState.DISCONNECTED;
7486
+ this.stopHeartbeatLoop();
7487
+ this.clearConnectTimeout();
7474
7488
  this.ondisconnect(evt);
7475
7489
  };
7476
- this.adapter.onError = (evt) => {
7477
- this.onerror(evt);
7478
- };
7479
7490
  this.adapter.onMessage = (message) => __async(this, null, function* () {
7480
7491
  if (this.verbose && window && window.console) {
7481
7492
  console.log("Response: %o", JSON.stringify(message));
@@ -7680,29 +7691,46 @@ var _DefaultSocket = class _DefaultSocket {
7680
7691
  }
7681
7692
  }
7682
7693
  });
7683
- return new Promise((resolve, reject) => {
7694
+ const connectPromise = new Promise((resolve, reject) => {
7684
7695
  this.adapter.onOpen = (evt) => {
7685
7696
  if (this.verbose && window && window.console) {
7686
7697
  console.log(evt);
7687
7698
  }
7688
- const isReconnect = this.hasConnectedBefore;
7689
- this.hasConnectedBefore = true;
7690
- this.pingPong();
7699
+ const isReconnect = __hasConnectedOnce;
7700
+ __hasConnectedOnce = true;
7701
+ this.clearConnectTimeout();
7702
+ this._connectionState = ConnectionState.CONNECTED;
7703
+ this.startHeartbeatLoop();
7704
+ this._connectPromise = void 0;
7691
7705
  resolve(session);
7692
7706
  if (isReconnect) {
7693
7707
  this.onreconnect(evt);
7694
7708
  }
7695
7709
  };
7696
7710
  this.adapter.onError = (evt) => {
7697
- reject(evt);
7711
+ this._connectionState = ConnectionState.DISCONNECTED;
7712
+ this.stopHeartbeatLoop();
7713
+ this.clearConnectTimeout();
7714
+ this.onerror(evt);
7715
+ this._connectPromise = void 0;
7698
7716
  this.adapter.close();
7717
+ reject(evt);
7699
7718
  };
7700
- setTimeout(() => {
7719
+ this._connectTimeoutTimer = setTimeout(() => {
7720
+ this._connectionState = ConnectionState.DISCONNECTED;
7721
+ this.stopHeartbeatLoop();
7722
+ this.adapter.close();
7723
+ this._connectPromise = void 0;
7701
7724
  reject("The socket timed out when trying to connect.");
7725
+ this._connectTimeoutTimer = void 0;
7702
7726
  }, connectTimeoutMs);
7703
7727
  });
7728
+ this._connectPromise = connectPromise;
7729
+ return this._connectPromise;
7704
7730
  }
7705
7731
  disconnect(fireDisconnectEvent = true) {
7732
+ this._connectionState = ConnectionState.DISCONNECTED;
7733
+ this.stopHeartbeatLoop();
7706
7734
  if (this.adapter.isOpen()) {
7707
7735
  this.adapter.close();
7708
7736
  }
@@ -7727,6 +7755,8 @@ var _DefaultSocket = class _DefaultSocket {
7727
7755
  }
7728
7756
  }
7729
7757
  onerror(evt) {
7758
+ this._connectionState = ConnectionState.DISCONNECTED;
7759
+ this.stopHeartbeatLoop();
7730
7760
  if (this.verbose && window && window.console) {
7731
7761
  console.log(evt);
7732
7762
  }
@@ -8097,9 +8127,11 @@ var _DefaultSocket = class _DefaultSocket {
8097
8127
  }
8098
8128
  const cid = this.generatecid();
8099
8129
  this.cIds[cid] = { resolve, reject };
8100
- setTimeout(() => {
8101
- reject("The socket timed out while waiting for a response.");
8102
- }, sendTimeout);
8130
+ if (sendTimeout !== Infinity && sendTimeout > 0) {
8131
+ setTimeout(() => {
8132
+ reject("The socket timed out while waiting for a response.");
8133
+ }, sendTimeout);
8134
+ }
8103
8135
  untypedMessage.cid = cid;
8104
8136
  this.adapter.send(untypedMessage);
8105
8137
  }
@@ -8292,7 +8324,7 @@ var _DefaultSocket = class _DefaultSocket {
8292
8324
  code,
8293
8325
  topic_id
8294
8326
  }
8295
- });
8327
+ }, Infinity);
8296
8328
  return response.channel_message_ack;
8297
8329
  });
8298
8330
  }
@@ -8497,12 +8529,16 @@ var _DefaultSocket = class _DefaultSocket {
8497
8529
  }
8498
8530
  pingPong() {
8499
8531
  return __async(this, null, function* () {
8500
- if (!this.adapter.isOpen()) {
8532
+ if (!this.isOpen()) {
8533
+ this._connectionState = ConnectionState.DISCONNECTED;
8534
+ this.stopHeartbeatLoop();
8501
8535
  return;
8502
8536
  }
8503
8537
  try {
8504
8538
  yield this.send({ ping: {} }, this._heartbeatTimeoutMs);
8505
8539
  } catch (e) {
8540
+ this._connectionState = ConnectionState.DISCONNECTED;
8541
+ this.stopHeartbeatLoop();
8506
8542
  if (this.adapter.isOpen()) {
8507
8543
  if (window && window.console) {
8508
8544
  console.error("Server unreachable from heartbeat.");
@@ -8512,9 +8548,28 @@ var _DefaultSocket = class _DefaultSocket {
8512
8548
  }
8513
8549
  return;
8514
8550
  }
8515
- setTimeout(() => this.pingPong(), this._heartbeatTimeoutMs);
8551
+ this.startHeartbeatLoop();
8516
8552
  });
8517
8553
  }
8554
+ startHeartbeatLoop() {
8555
+ this.stopHeartbeatLoop();
8556
+ this._heartbeatTimer = setTimeout(
8557
+ () => this.pingPong(),
8558
+ this._heartbeatTimeoutMs
8559
+ );
8560
+ }
8561
+ stopHeartbeatLoop() {
8562
+ if (this._heartbeatTimer !== void 0) {
8563
+ clearTimeout(this._heartbeatTimer);
8564
+ this._heartbeatTimer = void 0;
8565
+ }
8566
+ }
8567
+ clearConnectTimeout() {
8568
+ if (this._connectTimeoutTimer !== void 0) {
8569
+ clearTimeout(this._connectTimeoutTimer);
8570
+ this._connectTimeoutTimer = void 0;
8571
+ }
8572
+ }
8518
8573
  };
8519
8574
  _DefaultSocket.DefaultHeartbeatTimeoutMs = 1e4;
8520
8575
  _DefaultSocket.DefaultSendTimeoutMs = 1e4;
@@ -11232,6 +11287,7 @@ export {
11232
11287
  ChannelStreamMode,
11233
11288
  ChannelType,
11234
11289
  Client,
11290
+ ConnectionState,
11235
11291
  DefaultSocket,
11236
11292
  NotificationType,
11237
11293
  Session,
package/dist/socket.d.ts CHANGED
@@ -1073,7 +1073,12 @@ export interface SocketError {
1073
1073
  /** A message in English to help developers debug the response. */
1074
1074
  message: string;
1075
1075
  }
1076
- /** A socket connection to Mezon server implemented with the DOM's WebSocket API. */
1076
+ export declare const ConnectionState: {
1077
+ readonly DISCONNECTED: "disconnected";
1078
+ readonly CONNECTING: "connecting";
1079
+ readonly CONNECTED: "connected";
1080
+ };
1081
+ export type ConnectionStateType = typeof ConnectionState[keyof typeof ConnectionState];
1077
1082
  export declare class DefaultSocket implements Socket {
1078
1083
  readonly host: string;
1079
1084
  readonly port: string;
@@ -1087,7 +1092,10 @@ export declare class DefaultSocket implements Socket {
1087
1092
  private readonly cIds;
1088
1093
  private nextCid;
1089
1094
  private _heartbeatTimeoutMs;
1090
- private hasConnectedBefore;
1095
+ private _connectionState;
1096
+ private _heartbeatTimer?;
1097
+ private _connectTimeoutTimer?;
1098
+ private _connectPromise?;
1091
1099
  constructor(host: string, port: string, useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter, sendTimeoutMs?: number);
1092
1100
  generatecid(): string;
1093
1101
  isOpen(): boolean;
@@ -1196,5 +1204,8 @@ export declare class DefaultSocket implements Socket {
1196
1204
  writeChannelAppEvent(clan_id: string, channel_id: string, action: number): Promise<ChannelAppEvent>;
1197
1205
  listDataSocket(request: ListDataSocket): Promise<any>;
1198
1206
  private pingPong;
1207
+ private startHeartbeatLoop;
1208
+ private stopHeartbeatLoop;
1209
+ private clearConnectTimeout;
1199
1210
  }
1200
1211
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mezon-js",
3
- "version": "2.13.61",
3
+ "version": "2.13.62",
4
4
  "scripts": {
5
5
  "build": "npx tsc && npx rollup -c --bundleConfigAsCjs && node build.mjs"
6
6
  },
package/socket.ts CHANGED
@@ -1859,6 +1859,16 @@ export interface SocketError {
1859
1859
  }
1860
1860
 
1861
1861
  /** A socket connection to Mezon server implemented with the DOM's WebSocket API. */
1862
+ let __hasConnectedOnce = false;
1863
+
1864
+ export const ConnectionState = {
1865
+ DISCONNECTED: "disconnected",
1866
+ CONNECTING: "connecting",
1867
+ CONNECTED: "connected",
1868
+ } as const;
1869
+
1870
+ export type ConnectionStateType = typeof ConnectionState[keyof typeof ConnectionState];
1871
+
1862
1872
  export class DefaultSocket implements Socket {
1863
1873
  public static readonly DefaultHeartbeatTimeoutMs = 10000;
1864
1874
  public static readonly DefaultSendTimeoutMs = 10000;
@@ -1867,7 +1877,10 @@ export class DefaultSocket implements Socket {
1867
1877
  private readonly cIds: { [key: string]: PromiseExecutor };
1868
1878
  private nextCid: number;
1869
1879
  private _heartbeatTimeoutMs: number;
1870
- private hasConnectedBefore: boolean;
1880
+ private _connectionState: ConnectionStateType;
1881
+ private _heartbeatTimer?: ReturnType<typeof setTimeout>;
1882
+ private _connectTimeoutTimer?: ReturnType<typeof setTimeout>;
1883
+ private _connectPromise?: Promise<Session>;
1871
1884
 
1872
1885
  constructor(
1873
1886
  readonly host: string,
@@ -1880,7 +1893,7 @@ export class DefaultSocket implements Socket {
1880
1893
  this.cIds = {};
1881
1894
  this.nextCid = 1;
1882
1895
  this._heartbeatTimeoutMs = DefaultSocket.DefaultHeartbeatTimeoutMs;
1883
- this.hasConnectedBefore = false;
1896
+ this._connectionState = ConnectionState.DISCONNECTED;
1884
1897
  }
1885
1898
 
1886
1899
  generatecid(): string {
@@ -1890,7 +1903,7 @@ export class DefaultSocket implements Socket {
1890
1903
  }
1891
1904
 
1892
1905
  isOpen(): boolean {
1893
- return this.adapter.isOpen();
1906
+ return this._connectionState === ConnectionState.CONNECTED;
1894
1907
  }
1895
1908
 
1896
1909
  connect(
@@ -1900,10 +1913,17 @@ export class DefaultSocket implements Socket {
1900
1913
  connectTimeoutMs: number = DefaultSocket.DefaultConnectTimeoutMs,
1901
1914
  signal?: AbortSignal
1902
1915
  ): Promise<Session> {
1903
- if (this.adapter.isOpen()) {
1916
+ if (this._connectionState === ConnectionState.CONNECTED) {
1904
1917
  return Promise.resolve(session);
1905
1918
  }
1906
1919
 
1920
+ if (this._connectionState === ConnectionState.CONNECTING && this._connectPromise) {
1921
+ return this._connectPromise;
1922
+ }
1923
+
1924
+ this.clearConnectTimeout();
1925
+ this._connectionState = ConnectionState.CONNECTING;
1926
+
1907
1927
  const scheme = this.useSSL ? "wss://" : "ws://";
1908
1928
  this.adapter.connect(
1909
1929
  scheme,
@@ -1916,13 +1936,12 @@ export class DefaultSocket implements Socket {
1916
1936
  );
1917
1937
 
1918
1938
  this.adapter.onClose = (evt: Event) => {
1939
+ this._connectionState = ConnectionState.DISCONNECTED;
1940
+ this.stopHeartbeatLoop();
1941
+ this.clearConnectTimeout();
1919
1942
  this.ondisconnect(evt);
1920
1943
  };
1921
1944
 
1922
- this.adapter.onError = (evt: Event) => {
1923
- this.onerror(evt);
1924
- };
1925
-
1926
1945
  this.adapter.onMessage = async (message: any) => {
1927
1946
  if (this.verbose && window && window.console) {
1928
1947
  console.log("Response: %o", JSON.stringify(message));
@@ -2130,16 +2149,20 @@ export class DefaultSocket implements Socket {
2130
2149
  }
2131
2150
  };
2132
2151
 
2133
- return new Promise((resolve, reject) => {
2152
+ const connectPromise = new Promise<Session>((resolve, reject) => {
2134
2153
  this.adapter.onOpen = (evt: Event) => {
2135
2154
  if (this.verbose && window && window.console) {
2136
2155
  console.log(evt);
2137
2156
  }
2138
2157
 
2139
- const isReconnect = this.hasConnectedBefore;
2140
- this.hasConnectedBefore = true;
2158
+ const isReconnect = __hasConnectedOnce;
2159
+ __hasConnectedOnce = true;
2141
2160
 
2142
- this.pingPong();
2161
+ this.clearConnectTimeout();
2162
+ this._connectionState = ConnectionState.CONNECTED;
2163
+ this.startHeartbeatLoop();
2164
+ this._connectPromise = undefined;
2165
+
2143
2166
  resolve(session);
2144
2167
 
2145
2168
  if (isReconnect) {
@@ -2147,18 +2170,33 @@ export class DefaultSocket implements Socket {
2147
2170
  }
2148
2171
  };
2149
2172
  this.adapter.onError = (evt: Event) => {
2150
- reject(evt);
2173
+ this._connectionState = ConnectionState.DISCONNECTED;
2174
+ this.stopHeartbeatLoop();
2175
+ this.clearConnectTimeout();
2176
+ this.onerror(evt);
2177
+ this._connectPromise = undefined;
2151
2178
  this.adapter.close();
2179
+ reject(evt);
2152
2180
  };
2153
2181
 
2154
- setTimeout(() => {
2182
+ this._connectTimeoutTimer = setTimeout(() => {
2155
2183
  // if promise has resolved by now, the reject() is a no-op
2184
+ this._connectionState = ConnectionState.DISCONNECTED;
2185
+ this.stopHeartbeatLoop();
2186
+ this.adapter.close();
2187
+ this._connectPromise = undefined;
2156
2188
  reject("The socket timed out when trying to connect.");
2189
+ this._connectTimeoutTimer = undefined;
2157
2190
  }, connectTimeoutMs);
2158
2191
  });
2192
+
2193
+ this._connectPromise = connectPromise;
2194
+ return this._connectPromise;
2159
2195
  }
2160
2196
 
2161
2197
  disconnect(fireDisconnectEvent: boolean = true) {
2198
+ this._connectionState = ConnectionState.DISCONNECTED;
2199
+ this.stopHeartbeatLoop();
2162
2200
  if (this.adapter.isOpen()) {
2163
2201
  this.adapter.close();
2164
2202
  }
@@ -2188,6 +2226,8 @@ export class DefaultSocket implements Socket {
2188
2226
  }
2189
2227
 
2190
2228
  onerror(evt: Event) {
2229
+ this._connectionState = ConnectionState.DISCONNECTED;
2230
+ this.stopHeartbeatLoop();
2191
2231
  if (this.verbose && window && window.console) {
2192
2232
  console.log(evt);
2193
2233
  }
@@ -2653,11 +2693,12 @@ export class DefaultSocket implements Socket {
2653
2693
 
2654
2694
  const cid = this.generatecid();
2655
2695
  this.cIds[cid] = { resolve, reject };
2656
- setTimeout(() => {
2657
- reject("The socket timed out while waiting for a response.");
2658
- }, sendTimeout);
2696
+ if (sendTimeout !== Infinity && sendTimeout > 0) {
2697
+ setTimeout(() => {
2698
+ reject("The socket timed out while waiting for a response.");
2699
+ }, sendTimeout);
2700
+ }
2659
2701
 
2660
- /** Add id for promise executor. */
2661
2702
  untypedMessage.cid = cid;
2662
2703
  this.adapter.send(untypedMessage);
2663
2704
  }
@@ -2933,7 +2974,7 @@ export class DefaultSocket implements Socket {
2933
2974
  code: code,
2934
2975
  topic_id: topic_id,
2935
2976
  },
2936
- });
2977
+ }, Infinity);
2937
2978
  return response.channel_message_ack;
2938
2979
  }
2939
2980
 
@@ -3212,13 +3253,17 @@ export class DefaultSocket implements Socket {
3212
3253
  }
3213
3254
 
3214
3255
  private async pingPong(): Promise<void> {
3215
- if (!this.adapter.isOpen()) {
3256
+ if (!this.isOpen()) {
3257
+ this._connectionState = ConnectionState.DISCONNECTED;
3258
+ this.stopHeartbeatLoop();
3216
3259
  return;
3217
3260
  }
3218
3261
 
3219
3262
  try {
3220
3263
  await this.send({ ping: {} }, this._heartbeatTimeoutMs);
3221
3264
  } catch {
3265
+ this._connectionState = ConnectionState.DISCONNECTED;
3266
+ this.stopHeartbeatLoop();
3222
3267
  if (this.adapter.isOpen()) {
3223
3268
  if (window && window.console) {
3224
3269
  console.error("Server unreachable from heartbeat.");
@@ -3230,9 +3275,29 @@ export class DefaultSocket implements Socket {
3230
3275
  return;
3231
3276
  }
3232
3277
 
3233
- // reuse the timeout as the interval for now.
3234
- // we can separate them out into separate values if needed later.
3235
- setTimeout(() => this.pingPong(), this._heartbeatTimeoutMs);
3278
+ this.startHeartbeatLoop();
3279
+ }
3280
+
3281
+ private startHeartbeatLoop() {
3282
+ this.stopHeartbeatLoop();
3283
+ this._heartbeatTimer = setTimeout(
3284
+ () => this.pingPong(),
3285
+ this._heartbeatTimeoutMs
3286
+ );
3287
+ }
3288
+
3289
+ private stopHeartbeatLoop() {
3290
+ if (this._heartbeatTimer !== undefined) {
3291
+ clearTimeout(this._heartbeatTimer);
3292
+ this._heartbeatTimer = undefined;
3293
+ }
3294
+ }
3295
+
3296
+ private clearConnectTimeout() {
3297
+ if (this._connectTimeoutTimer !== undefined) {
3298
+ clearTimeout(this._connectTimeoutTimer);
3299
+ this._connectTimeoutTimer = undefined;
3300
+ }
3236
3301
  }
3237
3302
  }
3238
3303