aes70 2.0.14 → 2.0.16

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.
package/dist/AES70.es5.js CHANGED
@@ -31,12 +31,13 @@
31
31
  class Events {
32
32
  constructor() {
33
33
  this.event_handlers = new Map();
34
+ this.event_handlers_cleared = false;
34
35
  }
35
36
 
36
37
  /**
37
38
  * Emit an event.
38
39
  *
39
- * @param {String} name - Name of the event.
40
+ * @param {string} name - Name of the event.
40
41
  * @param {...*} args - Extra arguments.
41
42
  */
42
43
  emit(name) {
@@ -57,7 +58,7 @@
57
58
  /**
58
59
  * Subscribe to an event.
59
60
  *
60
- * @param {String} name - Name of the event.
61
+ * @param {string} name - Name of the event.
61
62
  * @param {Function} cb - Callback function.
62
63
  */
63
64
  on(name, cb) {
@@ -81,14 +82,17 @@
81
82
  /**
82
83
  * Removes an event handler.
83
84
  *
84
- * @param {String} name - Name of the event.
85
+ * @param {string} name - Name of the event.
85
86
  * @param {Function} cb - Callback function.
86
87
  */
87
88
  removeEventListener(name, cb) {
88
89
  const handlers = this.event_handlers.get(name);
89
90
 
90
91
  if (!handlers || !handlers.has(cb)) {
91
- throw new Error('removeEventListeners(): not installed.');
92
+ if (!this.event_handlers_cleared) {
93
+ console.warn('removeEventListeners(): not installed:', name, cb);
94
+ }
95
+ return;
92
96
  }
93
97
 
94
98
  handlers.delete(cb);
@@ -97,7 +101,7 @@
97
101
  /**
98
102
  * Removes an event handler.
99
103
  *
100
- * @param {strign} name
104
+ * @param {string} name
101
105
  * @param {Function} cb
102
106
  */
103
107
  off(name, cb) {
@@ -109,6 +113,7 @@
109
113
  */
110
114
  removeAllEventListeners() {
111
115
  this.event_handlers.clear();
116
+ this.event_handlers_cleared = true;
112
117
  }
113
118
 
114
119
  /**
@@ -934,6 +939,14 @@
934
939
  };
935
940
  }
936
941
 
942
+ get bufferedAmount() {
943
+ return this._currentSize;
944
+ }
945
+
946
+ get batchSize() {
947
+ return this._batchSize;
948
+ }
949
+
937
950
  add(pdu) {
938
951
  const currentSize = this._currentSize;
939
952
  const encodedLength = pdu.encoded_length();
@@ -966,7 +979,7 @@
966
979
  /* Keepalive packets are never combined into one message. */
967
980
  this._lastMessageType = messageType;
968
981
 
969
- if (this._currentSize > this._batchSize) {
982
+ if (this._currentSize + additionalSize > this._batchSize) {
970
983
  this.flush();
971
984
  } else if (this._pdus.length === 1) {
972
985
  this.scheduleFlush();
@@ -1031,6 +1044,130 @@
1031
1044
  }
1032
1045
  }
1033
1046
 
1047
+ function isItTime(target, now) {
1048
+ // We are ok with 1ms accuracy.
1049
+ return target - now < 1;
1050
+ }
1051
+
1052
+ class Timer {
1053
+ constructor(callback, getNow) {
1054
+ this._callback = callback;
1055
+ this._getNow = getNow;
1056
+ this._targetTime = undefined;
1057
+ this._timerId = undefined;
1058
+ this._timerAt = undefined;
1059
+ }
1060
+
1061
+ poll() {
1062
+ const now = this._getNow();
1063
+
1064
+ if (this._targetTime === undefined) return;
1065
+
1066
+ if (isItTime(this._targetTime, now)) {
1067
+ this._targetTime = undefined;
1068
+ try {
1069
+ this._callback();
1070
+ } catch (err) {
1071
+ console.error('Timer callback threw an exception', err);
1072
+ }
1073
+ } else {
1074
+ this._reschedule();
1075
+ }
1076
+ }
1077
+
1078
+ _reschedule() {
1079
+ const target = this._targetTime;
1080
+ const interval = target - this._getNow();
1081
+
1082
+ if (this._timerId !== undefined) {
1083
+ if (target >= this._timerAt) {
1084
+ // The timer will fire before target. We will then reschedule it.
1085
+ return;
1086
+ }
1087
+
1088
+ clearTimeout(this._timerId);
1089
+ this._timerId = undefined;
1090
+ }
1091
+
1092
+ this._timerAt = target;
1093
+ this._timerId = setTimeout(() => {
1094
+ this._timerId = undefined;
1095
+ this._timerAt = undefined;
1096
+ this.poll();
1097
+ }, Math.max(0, interval));
1098
+ }
1099
+
1100
+ /**
1101
+ *
1102
+ * @param {number} interval
1103
+ * Interval in milliseconds.
1104
+ */
1105
+ scheduleIn(interval) {
1106
+ if (!(interval >= 0)) {
1107
+ throw new TypeError(`Expected positive interval.`);
1108
+ }
1109
+
1110
+ this._targetTime = this._getNow() + interval;
1111
+ this._reschedule();
1112
+ }
1113
+
1114
+ /**
1115
+ * Schedule the timer in a given number of milliseconds. If the timer
1116
+ * is already running and scheduled to run before, do not modify it.
1117
+ *
1118
+ * @param {number} interval
1119
+ */
1120
+ scheduleDeadlineIn(interval) {
1121
+ if (!(interval >= 0)) {
1122
+ throw new TypeError(`Expected positive interval.`);
1123
+ }
1124
+
1125
+ const target = this._getNow() + interval;
1126
+
1127
+ if (this._targetTime !== undefined && this._targetTime <= target) {
1128
+ this.poll();
1129
+ return;
1130
+ }
1131
+
1132
+ this.scheduleAt(target);
1133
+ }
1134
+
1135
+ /**
1136
+ *
1137
+ * @param {number} target
1138
+ * Target time in milliseconds.
1139
+ */
1140
+ scheduleAt(target) {
1141
+ if (!(target >= 0)) {
1142
+ throw new TypeError();
1143
+ }
1144
+
1145
+ this._targetTime = target;
1146
+ this._reschedule();
1147
+ }
1148
+
1149
+ stop() {
1150
+ this._targetTime = undefined;
1151
+ }
1152
+
1153
+ cancel() {
1154
+ this.stop();
1155
+ this._clearTimeout();
1156
+ }
1157
+
1158
+ _clearTimeout() {
1159
+ if (this._timerId) {
1160
+ clearTimeout(this._timerId);
1161
+ this._timerId = undefined;
1162
+ this._timerAt = undefined;
1163
+ }
1164
+ }
1165
+
1166
+ dispose() {
1167
+ this.cancel();
1168
+ }
1169
+ }
1170
+
1034
1171
  /**
1035
1172
  * Connection base class. It extends :class:`Events` and defines two events:
1036
1173
  *
@@ -1067,8 +1204,11 @@
1067
1204
  this.last_tx_time = now;
1068
1205
  this.rx_bytes = 0;
1069
1206
  this.tx_bytes = 0;
1207
+ this._keepalive_timer = new Timer(
1208
+ () => this._check_keepalive(),
1209
+ () => this._now()
1210
+ );
1070
1211
  this.keepalive_interval = -1;
1071
- this._keepalive_interval_id = null;
1072
1212
  this._closed = false;
1073
1213
  this.on('close', () => {
1074
1214
  if (this._closed) return;
@@ -1087,6 +1227,18 @@
1087
1227
  return true;
1088
1228
  }
1089
1229
 
1230
+ get bufferedAmount() {
1231
+ return this._message_generator.bufferedAmount;
1232
+ }
1233
+
1234
+ get batchSize() {
1235
+ return this._message_generator.batchSize;
1236
+ }
1237
+
1238
+ get pendingWrites() {
1239
+ return this._message_generator.bufferedAmount > 0 ? 1 : 0;
1240
+ }
1241
+
1090
1242
  send(pdu) {
1091
1243
  if (this.is_closed()) throw new Error('Connection is closed.');
1092
1244
  this.emit('send', pdu);
@@ -1144,7 +1296,7 @@
1144
1296
  }
1145
1297
  }
1146
1298
 
1147
- this._check_keepalive();
1299
+ this.poll();
1148
1300
  }
1149
1301
 
1150
1302
  incoming(a) {}
@@ -1175,16 +1327,18 @@
1175
1327
  if (this.is_closed()) throw new Error('cleanup() called twice.');
1176
1328
 
1177
1329
  // disable keepalive
1178
- this.set_keepalive_interval(0);
1330
+ this._keepalive_timer.dispose();
1179
1331
  this._message_generator.dispose();
1180
1332
  this._message_generator = null;
1181
1333
  this.removeAllEventListeners();
1182
1334
  }
1183
1335
 
1184
1336
  _check_keepalive() {
1185
- if (!(this.keepalive_interval > 0)) return;
1186
-
1337
+ if (this.is_closed()) return;
1187
1338
  const t = this.keepalive_interval;
1339
+ if (!(t > 0)) return;
1340
+
1341
+ this._keepalive_timer.scheduleIn(t / 2 + 10);
1188
1342
 
1189
1343
  if (this.rx_idle_time() > t * 3) {
1190
1344
  this.emit('timeout');
@@ -1196,6 +1350,13 @@
1196
1350
  }
1197
1351
  }
1198
1352
 
1353
+ /**
1354
+ * Check if some regular internal timers must run.
1355
+ */
1356
+ poll() {
1357
+ this._keepalive_timer.poll();
1358
+ }
1359
+
1199
1360
  /**
1200
1361
  * Flush write buffers. This are usually PDUs or may also be unwritten
1201
1362
  * buffers.
@@ -1221,11 +1382,6 @@
1221
1382
 
1222
1383
  const t = seconds * 1000;
1223
1384
 
1224
- if (this._keepalive_interval_id !== null) {
1225
- clearInterval(this._keepalive_interval_id);
1226
- this._keepalive_interval_id = null;
1227
- }
1228
-
1229
1385
  this.keepalive_interval = t;
1230
1386
 
1231
1387
  // Notify the other side about our new keepalive
@@ -1233,12 +1389,12 @@
1233
1389
 
1234
1390
  this.send(new KeepAlive(t));
1235
1391
 
1236
- if (!(t > 0)) return;
1237
-
1238
- // we check twice as often to make sure we stay within the timers
1239
- this._keepalive_interval_id = setInterval(() => {
1240
- this._check_keepalive();
1241
- }, t / 2);
1392
+ if (t > 0) {
1393
+ // we check twice as often to make sure we stay within the timers
1394
+ this._keepalive_timer.scheduleIn(t / 2 + 10);
1395
+ } else {
1396
+ this._keepalive_timer.stop();
1397
+ }
1242
1398
  }
1243
1399
  }
1244
1400
 
@@ -1585,6 +1741,67 @@
1585
1741
  }
1586
1742
  }
1587
1743
 
1744
+ class Subscriptions {
1745
+ constructor() {
1746
+ this._callbacks = [];
1747
+ }
1748
+
1749
+ /**
1750
+ * Add a subscription.
1751
+ *
1752
+ * @param {Function[]} cbs
1753
+ */
1754
+ add(...cbs) {
1755
+ cbs.forEach((cb) => {
1756
+ this._callbacks.push(cb);
1757
+ });
1758
+ }
1759
+
1760
+ unsubscribe() {
1761
+ this._callbacks.forEach((cb) => {
1762
+ try {
1763
+ cb();
1764
+ } catch (err) {
1765
+ console.error(err);
1766
+ }
1767
+ });
1768
+ this._callbacks.length = 0;
1769
+ }
1770
+ }
1771
+
1772
+ function addEvent(target, name, callback) {
1773
+ if (target.addEventListener) {
1774
+ target.addEventListener(name, callback);
1775
+ } else if (target.on) {
1776
+ target.on(name, callback);
1777
+ } else {
1778
+ throw new TypeError('Unsupported event target ', target);
1779
+ }
1780
+ }
1781
+
1782
+ function removeEvent(target, name, callback) {
1783
+ if (target.removeEventListener) {
1784
+ target.removeEventListener(name, callback);
1785
+ } else if (target.off) {
1786
+ target.off(name, callback);
1787
+ } else {
1788
+ throw new TypeError('Unsupported event target ', target);
1789
+ }
1790
+ }
1791
+
1792
+ /**
1793
+ *
1794
+ * @param {EventTarget|Events} target
1795
+ * @param {string} name
1796
+ * @param {callback} callback
1797
+ */
1798
+ function subscribeEvent(target, name, callback) {
1799
+ addEvent(target, name, callback);
1800
+ return () => {
1801
+ removeEvent(target, name, callback);
1802
+ };
1803
+ }
1804
+
1588
1805
  class PendingCommand {
1589
1806
  get handle() {
1590
1807
  return this.command.handle;
@@ -1663,17 +1880,57 @@
1663
1880
  class ClientConnection extends Connection {
1664
1881
  constructor(options) {
1665
1882
  super(options);
1883
+ // All pending commands by id/handle
1666
1884
  this._pendingCommands = new Map();
1885
+ // All pending commands scheduled to be sent.
1886
+ this._scheduledPendingCommands = new Set();
1887
+ // All pending commands wich have been sent.
1888
+ this._sentPendingCommands = new Set();
1667
1889
  this._nextCommandHandle = 0;
1668
1890
  this._subscribers = new Map();
1891
+ this._sendCommandsTimer = new Timer(
1892
+ () => {
1893
+ this.sendCommands();
1894
+ },
1895
+ () => this._now()
1896
+ );
1897
+ }
1898
+
1899
+ shouldSendMoreCommands() {
1900
+ return this.is_reliable;
1901
+ }
1902
+
1903
+ sendCommands() {
1904
+ const { _scheduledPendingCommands, _sentPendingCommands } = this;
1905
+
1906
+ for (const pendingCommand of _scheduledPendingCommands) {
1907
+ if (!this.shouldSendMoreCommands()) break;
1908
+ _scheduledPendingCommands.delete(pendingCommand);
1909
+ _sentPendingCommands.add(pendingCommand);
1910
+ this.send(pendingCommand.command);
1911
+ pendingCommand.lastSent = this._now();
1912
+ pendingCommand.retries++;
1913
+ }
1914
+ }
1915
+
1916
+ scheduleSendCommands() {
1917
+ this._sendCommandsTimer.scheduleDeadlineIn(5);
1918
+ }
1919
+
1920
+ poll() {
1921
+ super.poll();
1922
+ this._sendCommandsTimer.poll();
1669
1923
  }
1670
1924
 
1671
1925
  cleanup(error) {
1672
1926
  super.cleanup(error);
1927
+ this._sendCommandsTimer.dispose();
1673
1928
  const subscribers = this._subscribers;
1674
1929
  this._subscribers = null;
1675
1930
  const pendingCommands = this._pendingCommands;
1676
1931
  this._pendingCommands = null;
1932
+ this._scheduledPendingCommands.clear();
1933
+ this._sentPendingCommands.clear();
1677
1934
 
1678
1935
  const e = new CloseError(error);
1679
1936
  pendingCommands.forEach((pendingCommand, id) => {
@@ -1752,9 +2009,8 @@
1752
2009
  );
1753
2010
 
1754
2011
  this._pendingCommands.set(handle, pendingCommand);
1755
-
1756
- pendingCommand.lastSent = this._estimate_next_tx_time();
1757
- this.send(command);
2012
+ this._scheduledPendingCommands.add(pendingCommand);
2013
+ this.scheduleSendCommands();
1758
2014
  };
1759
2015
 
1760
2016
  if (callback) {
@@ -1775,6 +2031,9 @@
1775
2031
 
1776
2032
  pendingCommands.delete(handle);
1777
2033
 
2034
+ if (!this._sentPendingCommands.delete(pendingCommand))
2035
+ this._scheduledPendingCommands.delete(pendingCommand);
2036
+
1778
2037
  return pendingCommand;
1779
2038
  }
1780
2039
 
@@ -1829,35 +2088,34 @@
1829
2088
  * the connection will be closed and the returned promise will reject.
1830
2089
  * @param {number} interval
1831
2090
  * Keepalive interval in seconds.
2091
+ * @param {AbortSignal} [signal]
2092
+ * Optional abort signal which can be used to abort
2093
+ * the process.
1832
2094
  */
1833
- wait_for_keepalive(interval) {
1834
- return new Promise((resolve, reject) => {
1835
- const subscriptions = [];
2095
+ wait_for_keepalive(interval, signal) {
2096
+ const subscriptions = new Subscriptions();
1836
2097
 
1837
- const cleanup = () => {
1838
- subscriptions.forEach((cb) => {
1839
- try {
1840
- cb();
1841
- } catch (e) {}
1842
- });
1843
- subscriptions.length = 0;
1844
- };
1845
- subscriptions.push(
2098
+ return new Promise((resolve, reject) => {
2099
+ if (signal) {
2100
+ subscriptions.add(
2101
+ subscribeEvent(signal, 'abort', () => {
2102
+ reject(signal.reason);
2103
+ })
2104
+ );
2105
+ }
2106
+ subscriptions.add(
1846
2107
  this.subscribe('error', (error) => {
1847
2108
  reject(error);
1848
- cleanup();
1849
2109
  }),
1850
2110
  this.subscribe('close', () => {
1851
2111
  reject(new CloseError());
1852
- cleanup();
1853
2112
  }),
1854
2113
  this.subscribe('keepalive', () => {
1855
2114
  resolve();
1856
- cleanup();
1857
2115
  })
1858
2116
  );
1859
2117
  this.set_keepalive_interval(interval);
1860
- });
2118
+ }).finally(() => subscriptions.unsubscribe());
1861
2119
  }
1862
2120
  }
1863
2121
 
@@ -3486,8 +3744,7 @@
3486
3744
  * @returns {Function} The getter. If none could be found, null is returned.
3487
3745
  */
3488
3746
  getter(o, no_bind) {
3489
- let name = this.name;
3490
- let i = 0;
3747
+ const name = this.name;
3491
3748
  const aliases = this.aliases;
3492
3749
  const accessors = this.accessors;
3493
3750
 
@@ -3529,10 +3786,13 @@
3529
3786
  return no_bind ? fun : fun.bind(o);
3530
3787
  }
3531
3788
 
3532
- do {
3789
+ // iterate all possible names
3790
+ const possibleNames = aliases ? [name, ...aliases] : [name];
3791
+
3792
+ for (const possibleName of possibleNames) {
3533
3793
  if (this.static) {
3534
3794
  const c = o.constructor;
3535
- const v = c[name];
3795
+ const v = c[possibleName];
3536
3796
 
3537
3797
  if (v !== void 0) {
3538
3798
  return function () {
@@ -3540,16 +3800,11 @@
3540
3800
  };
3541
3801
  }
3542
3802
  } else {
3543
- const fun = o['Get' + name];
3803
+ const fun = o['Get' + possibleName];
3544
3804
 
3545
3805
  if (fun) return no_bind ? fun : fun.bind(o);
3546
3806
  }
3547
-
3548
- if (aliases && i < aliases.length) {
3549
- name = aliases[i++];
3550
- continue;
3551
- }
3552
- } while (false);
3807
+ }
3553
3808
 
3554
3809
  return null;
3555
3810
  }
@@ -3565,20 +3820,15 @@
3565
3820
  setter(o, no_bind) {
3566
3821
  if (this.readonly || this.static) return null;
3567
3822
 
3568
- let name = this.name,
3569
- i = 0;
3823
+ const name = this.name;
3570
3824
  const aliases = this.aliases;
3825
+ const possibleNames = aliases ? [name, ...aliases] : [name];
3571
3826
 
3572
- do {
3573
- const fun = o['Set' + name];
3827
+ for (const possibleName of possibleNames) {
3828
+ const fun = o['Set' + possibleName];
3574
3829
 
3575
3830
  if (fun) return no_bind ? fun : fun.bind(o);
3576
-
3577
- if (aliases && i < aliases.length) {
3578
- name = aliases[i++];
3579
- continue;
3580
- }
3581
- } while (false);
3831
+ }
3582
3832
 
3583
3833
  return null;
3584
3834
  }
@@ -28733,35 +28983,6 @@
28733
28983
 
28734
28984
  /* eslint-env node */
28735
28985
 
28736
-
28737
- function delay(n) {
28738
- return new Promise((resolve) => setTimeout(resolve, n));
28739
- }
28740
-
28741
- async function waitForKeepalive(socket, options) {
28742
- const waiter = socket.receiveMessage().then((buffer) => {
28743
- const pdus = [];
28744
- const pos = decodeMessage(new DataView(buffer), 0, pdus);
28745
-
28746
- if (pdus.length !== 1) throw new Error('Expected keepalive response.');
28747
- if (pos !== buffer.byteLength)
28748
- throw new Error('Trailing data in initial keepalive pdu.');
28749
-
28750
- return true;
28751
- });
28752
-
28753
- const msg = encodeMessage(new KeepAlive(1000));
28754
- const t = 5 * (options.retry_interval || 250);
28755
-
28756
- for (let i = 0; i < 3; i++) {
28757
- socket.send(msg);
28758
-
28759
- if (await Promise.race([waiter, delay(t)])) return;
28760
- }
28761
-
28762
- throw new Error('Failed to connect.');
28763
- }
28764
-
28765
28986
  /**
28766
28987
  * :class:`ClientConnection` subclass which implements OCP.1 with UDP
28767
28988
  * transport.
@@ -28778,15 +28999,20 @@
28778
28999
  this.retry_interval =
28779
29000
  options.retry_interval >= 0 ? options.retry_interval : 250;
28780
29001
  this.retry_count = options.retry_count >= 0 ? options.retry_count : 3;
28781
- this._write_out_id = -1;
28782
- this._write_out_callback = () => {
28783
- this._write_out_id = -1;
28784
- this._write_out();
28785
- };
28786
- this._retry_id =
28787
- this.retry_interval > 0
28788
- ? setInterval(() => this._retryCommands(), this.retry_interval)
28789
- : -1;
29002
+ this._write_out_timer = new Timer(
29003
+ () => {
29004
+ this._write_out();
29005
+ },
29006
+ () => this._now()
29007
+ );
29008
+ this._retry_timer = new Timer(
29009
+ () => {
29010
+ this._retryCommands();
29011
+ this._retry_timer.scheduleIn(this.retry_interval);
29012
+ },
29013
+ () => this._now()
29014
+ );
29015
+ this._retry_timer.scheduleIn(this.retry_interval);
28790
29016
  this.q = [];
28791
29017
  socket.onmessage = (buffer) => {
28792
29018
  try {
@@ -28804,11 +29030,33 @@
28804
29030
  return false;
28805
29031
  }
28806
29032
 
29033
+ get bufferedAmount() {
29034
+ let amount = super.bufferedAmount;
29035
+
29036
+ for (const buf of this.q) {
29037
+ amount += buf.byteLength;
29038
+ }
29039
+
29040
+ return amount;
29041
+ }
29042
+
29043
+ get pendingWrites() {
29044
+ return super.pendingWrites + this.q.length;
29045
+ }
29046
+
29047
+ shouldSendMoreCommands() {
29048
+ return this.q.length < 3;
29049
+ }
29050
+
28807
29051
  /**
28808
29052
  * Connect to the given endpoint.
28809
29053
  *
28810
- * @param {String} options.host - hostname or ip
28811
- * @param {number} options.port - port number
29054
+ * @param {String} options.host
29055
+ * Hostname or ip address.
29056
+ * @param {number} options.port
29057
+ * Port number.
29058
+ * @param {'udp4' | 'udp6'} [options.type]
29059
+ * Optional ip protocol type.
28812
29060
  * @param {number} [options.delay=10] - Delay in ms between individual packets.
28813
29061
  * This can be a useful strategy when communicating with devices which
28814
29062
  * cannot handle high packet rates.
@@ -28822,23 +29070,33 @@
28822
29070
  * in an individual UDP packet. Note that AES70 messages which are larger
28823
29071
  * than this limit are sent anyway. This only limits how many seperate
28824
29072
  * messages are batched into a single packet.
28825
- * @returns {Promise<UDPConnection>}
29073
+ * @param {AbortSignal} [options.connectSignal]
29074
+ * An optional AbortSignal which can be used to abort the connect attempt.
29075
+ * Note that this is different from the `signal` option which will destroy
29076
+ * the socket also after the connect attempt has been successful.
29077
+ * @returns {Promise<AbstractUDPConnection>}
28826
29078
  * The connection.
28827
29079
  */
28828
29080
  static async connect(udpApi, options) {
28829
- const socket = await udpApi.connect(
28830
- options.host,
28831
- options.port,
28832
- options.type
28833
- );
29081
+ const { host, port, type, connectSignal } = options;
29082
+ const socket = await udpApi.connect({
29083
+ host,
29084
+ port,
29085
+ type,
29086
+ signal: connectSignal,
29087
+ });
29088
+
29089
+ const connection = new this(socket, options);
28834
29090
 
28835
29091
  try {
28836
- await waitForKeepalive(socket, options);
28837
- return new this(socket, options);
29092
+ await connection.wait_for_keepalive(1, connectSignal);
29093
+ connectSignal?.throwIfAborted();
28838
29094
  } catch (err) {
28839
- socket.close();
29095
+ connection.close();
28840
29096
  throw err;
28841
29097
  }
29098
+
29099
+ return connection;
28842
29100
  }
28843
29101
 
28844
29102
  write(buf) {
@@ -28859,14 +29117,8 @@
28859
29117
  this.socket.close();
28860
29118
  this.socket = null;
28861
29119
  }
28862
- if (this._write_out_id !== -1) {
28863
- clearTimeout(this._write_out_id);
28864
- this._write_out_id = -1;
28865
- }
28866
- if (this._retry_id !== -1) {
28867
- clearInterval(this._retry_id);
28868
- this._retry_id = -1;
28869
- }
29120
+ this._write_out_timer.dispose();
29121
+ this._retry_timer.dispose();
28870
29122
  }
28871
29123
 
28872
29124
  _estimate_next_tx_time() {
@@ -28885,6 +29137,13 @@
28885
29137
  super.write(buf);
28886
29138
 
28887
29139
  if (q.length) this._schedule_write_out();
29140
+ this.scheduleSendCommands();
29141
+ }
29142
+
29143
+ poll() {
29144
+ super.poll();
29145
+ this._write_out_timer.poll();
29146
+ this._retry_timer.poll();
28888
29147
  }
28889
29148
 
28890
29149
  _schedule_write_out() {
@@ -28896,38 +29155,36 @@
28896
29155
  return;
28897
29156
  }
28898
29157
 
28899
- // Already scheduled.
28900
- if (this._write_out_id !== -1) return;
28901
-
28902
- this._write_out_id = setTimeout(
28903
- this._write_out_callback,
28904
- delay - tx_idle_time
28905
- );
29158
+ this._write_out_timer.scheduleIn(delay - tx_idle_time);
28906
29159
  }
28907
29160
 
28908
29161
  _retryCommands() {
28909
29162
  const now = this._now();
28910
29163
  const retryTime = now - this.retry_interval;
28911
- // This is an estimate for how many commands we would manage to send
28912
- // off.
28913
- const max = 5 * (this.retry_interval / this.delay) - this.q.length;
28914
29164
  const pendingCommands = this._pendingCommands;
29165
+ const _sentPendingCommands = this._sentPendingCommands;
29166
+ const _scheduledPendingCommands = this._scheduledPendingCommands;
28915
29167
 
28916
- const retries = [];
29168
+ let scheduledCount = 0;
28917
29169
  const failed = [];
28918
29170
 
28919
- for (const entry of pendingCommands) {
28920
- const [, pendingCommand] = entry;
28921
-
28922
- // All later commands are newer than the cutoff.
29171
+ for (const pendingCommand of _sentPendingCommands) {
28923
29172
  if (pendingCommand.lastSent > retryTime) break;
29173
+
29174
+ _sentPendingCommands.delete(pendingCommand);
29175
+
28924
29176
  if (pendingCommand.retries >= this.retry_count) {
28925
- failed.push(entry);
28926
- } else if (retries.length < max) {
28927
- retries.push(entry);
29177
+ failed.push(pendingCommand);
29178
+ } else {
29179
+ _scheduledPendingCommands.add(pendingCommand);
29180
+ scheduledCount++;
28928
29181
  }
28929
29182
  }
28930
29183
 
29184
+ if (scheduledCount) {
29185
+ this.scheduleSendCommands();
29186
+ }
29187
+
28931
29188
  if (failed.length) {
28932
29189
  const timeoutError = new Error('Timeout.');
28933
29190
 
@@ -28936,14 +29193,6 @@
28936
29193
  pendingCommand.reject(timeoutError);
28937
29194
  });
28938
29195
  }
28939
-
28940
- retries.forEach(([handle, pendingCommand]) => {
28941
- pendingCommands.delete(handle);
28942
- pendingCommands.set(handle, pendingCommand);
28943
- this.send(pendingCommand.command);
28944
- pendingCommand.lastSent = now;
28945
- pendingCommand.retries++;
28946
- });
28947
29196
  }
28948
29197
  }
28949
29198
 
@@ -29072,6 +29321,10 @@
29072
29321
  }
29073
29322
  return value;
29074
29323
  }
29324
+ } else if (typeof value === 'bigint') {
29325
+ return value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER
29326
+ ? Number(value)
29327
+ : value.toString();
29075
29328
  } else {
29076
29329
  return value;
29077
29330
  }