@nktkas/hyperliquid 0.17.4 → 0.18.1

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 (106) hide show
  1. package/README.md +48 -36
  2. package/esm/deps/jsr.io/@std/async/1.0.12/delay.d.ts +43 -0
  3. package/esm/deps/jsr.io/@std/async/1.0.12/delay.d.ts.map +1 -0
  4. package/esm/deps/jsr.io/@std/async/1.0.12/delay.js +63 -0
  5. package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common16.d.ts +1 -1
  6. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +1 -0
  7. package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common16.js +1 -1
  8. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +1 -0
  9. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +1 -0
  10. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +1 -0
  11. package/esm/src/base.d.ts +2 -2
  12. package/esm/src/base.d.ts.map +1 -1
  13. package/esm/src/clients/event.d.ts +2 -1
  14. package/esm/src/clients/event.d.ts.map +1 -1
  15. package/esm/src/clients/event.js +3 -0
  16. package/esm/src/clients/public.d.ts +2 -1
  17. package/esm/src/clients/public.d.ts.map +1 -1
  18. package/esm/src/clients/public.js +3 -0
  19. package/esm/src/clients/wallet.d.ts +24 -13
  20. package/esm/src/clients/wallet.d.ts.map +1 -1
  21. package/esm/src/clients/wallet.js +88 -62
  22. package/esm/src/signing.d.ts +4 -1
  23. package/esm/src/signing.d.ts.map +1 -1
  24. package/esm/src/signing.js +46 -23
  25. package/esm/src/transports/http/http_transport.d.ts +9 -60
  26. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  27. package/esm/src/transports/http/http_transport.js +9 -57
  28. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +3 -12
  29. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  30. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +22 -44
  31. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  32. package/esm/src/transports/websocket/_reconnecting_websocket.js +127 -193
  33. package/esm/src/transports/websocket/websocket_transport.d.ts +8 -1
  34. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  35. package/esm/src/transports/websocket/websocket_transport.js +26 -21
  36. package/esm/src/types/exchange/requests.d.ts +26 -2
  37. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  38. package/esm/src/types/exchange/responses.d.ts +6 -6
  39. package/esm/src/types/exchange/responses.d.ts.map +1 -1
  40. package/esm/src/types/info/accounts.d.ts +14 -0
  41. package/esm/src/types/info/accounts.d.ts.map +1 -1
  42. package/esm/src/types/info/assets.d.ts +18 -0
  43. package/esm/src/types/info/assets.d.ts.map +1 -1
  44. package/package.json +2 -1
  45. package/script/deps/jsr.io/@std/async/1.0.12/delay.d.ts +43 -0
  46. package/script/deps/jsr.io/@std/async/1.0.12/delay.d.ts.map +1 -0
  47. package/script/deps/jsr.io/@std/async/1.0.12/delay.js +76 -0
  48. package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common16.d.ts +1 -1
  49. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +1 -0
  50. package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common16.js +1 -1
  51. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +1 -0
  52. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +1 -0
  53. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +1 -0
  54. package/script/src/base.d.ts +2 -2
  55. package/script/src/base.d.ts.map +1 -1
  56. package/script/src/clients/event.d.ts +2 -1
  57. package/script/src/clients/event.d.ts.map +1 -1
  58. package/script/src/clients/event.js +3 -0
  59. package/script/src/clients/public.d.ts +2 -1
  60. package/script/src/clients/public.d.ts.map +1 -1
  61. package/script/src/clients/public.js +3 -0
  62. package/script/src/clients/wallet.d.ts +24 -13
  63. package/script/src/clients/wallet.d.ts.map +1 -1
  64. package/script/src/clients/wallet.js +88 -62
  65. package/script/src/signing.d.ts +4 -1
  66. package/script/src/signing.d.ts.map +1 -1
  67. package/script/src/signing.js +46 -23
  68. package/script/src/transports/http/http_transport.d.ts +9 -60
  69. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  70. package/script/src/transports/http/http_transport.js +9 -57
  71. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +3 -12
  72. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  73. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +22 -44
  74. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  75. package/script/src/transports/websocket/_reconnecting_websocket.js +129 -195
  76. package/script/src/transports/websocket/websocket_transport.d.ts +8 -1
  77. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  78. package/script/src/transports/websocket/websocket_transport.js +26 -21
  79. package/script/src/types/exchange/requests.d.ts +26 -2
  80. package/script/src/types/exchange/requests.d.ts.map +1 -1
  81. package/script/src/types/exchange/responses.d.ts +6 -6
  82. package/script/src/types/exchange/responses.d.ts.map +1 -1
  83. package/script/src/types/info/accounts.d.ts +14 -0
  84. package/script/src/types/info/accounts.d.ts.map +1 -1
  85. package/script/src/types/info/assets.d.ts +18 -0
  86. package/script/src/types/info/assets.d.ts.map +1 -1
  87. package/esm/deps/jsr.io/@std/encoding/1.0.9/_common16.d.ts.map +0 -1
  88. package/esm/deps/jsr.io/@std/encoding/1.0.9/_common_detach.d.ts.map +0 -1
  89. package/esm/deps/jsr.io/@std/encoding/1.0.9/_types.d.ts.map +0 -1
  90. package/esm/deps/jsr.io/@std/encoding/1.0.9/hex.d.ts.map +0 -1
  91. package/script/deps/jsr.io/@std/encoding/1.0.9/_common16.d.ts.map +0 -1
  92. package/script/deps/jsr.io/@std/encoding/1.0.9/_common_detach.d.ts.map +0 -1
  93. package/script/deps/jsr.io/@std/encoding/1.0.9/_types.d.ts.map +0 -1
  94. package/script/deps/jsr.io/@std/encoding/1.0.9/hex.d.ts.map +0 -1
  95. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common_detach.d.ts +0 -0
  96. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common_detach.js +0 -0
  97. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_types.d.ts +0 -0
  98. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_types.js +0 -0
  99. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/hex.d.ts +0 -0
  100. /package/esm/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/hex.js +0 -0
  101. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common_detach.d.ts +0 -0
  102. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_common_detach.js +0 -0
  103. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_types.d.ts +0 -0
  104. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/_types.js +0 -0
  105. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/hex.d.ts +0 -0
  106. /package/script/deps/jsr.io/@std/encoding/{1.0.9 → 1.0.10}/hex.js +0 -0
@@ -1,4 +1,5 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
+ import { delay } from "../../../deps/jsr.io/@std/async/1.0.12/delay.js";
2
3
  import { TransportError } from "../../base.js";
3
4
  /** Simple FIFO (First In, First Out) buffer implementation. */
4
5
  class FIFOMessageBuffer {
@@ -44,192 +45,174 @@ export class ReconnectingWebSocketError extends TransportError {
44
45
  * Fully compatible with standard WebSocket API.
45
46
  */
46
47
  export class ReconnectingWebSocket {
47
- /**
48
- * Creates a new reconnecting WebSocket.
49
- * @param url - The WebSocket URL to connect to.
50
- * @param protocols - The WebSocket protocols to use.
51
- * @param options - The configuration options.
52
- */
53
48
  constructor(url, protocols, options) {
54
- /** Controller for handling connection termination. */
55
- Object.defineProperty(this, "_terminationController", {
56
- enumerable: true,
57
- configurable: true,
58
- writable: true,
59
- value: new AbortController()
60
- });
61
- /** WebSocket protocols defined in constructor. */
62
- Object.defineProperty(this, "_protocols", {
63
- enumerable: true,
64
- configurable: true,
65
- writable: true,
66
- value: void 0
67
- });
68
- /** Non-permanent original instance of WebSocket. */
69
49
  Object.defineProperty(this, "_socket", {
70
50
  enumerable: true,
71
51
  configurable: true,
72
52
  writable: true,
73
53
  value: void 0
74
54
  });
75
- /** Current number of reconnection attempts */
76
- Object.defineProperty(this, "_reconnectCount", {
55
+ Object.defineProperty(this, "_protocols", {
77
56
  enumerable: true,
78
57
  configurable: true,
79
58
  writable: true,
80
- value: 0
59
+ value: void 0
81
60
  });
82
- /** The array of registered event listeners to recover from reconnection. */
83
- Object.defineProperty(this, "_eventListeners", {
61
+ Object.defineProperty(this, "_listeners", {
84
62
  enumerable: true,
85
63
  configurable: true,
86
64
  writable: true,
87
65
  value: []
88
66
  });
89
- /** WebSocket event handlers for reconnection. */
90
- Object.defineProperty(this, "_onclose", {
67
+ Object.defineProperty(this, "_attempt", {
91
68
  enumerable: true,
92
69
  configurable: true,
93
70
  writable: true,
94
- value: void 0
71
+ value: 0
95
72
  });
96
- /** WebSocket event handlers for reconnection. */
97
- Object.defineProperty(this, "_onerror", {
73
+ Object.defineProperty(this, "reconnectOptions", {
98
74
  enumerable: true,
99
75
  configurable: true,
100
76
  writable: true,
101
77
  value: void 0
102
78
  });
103
- /** WebSocket event handlers for reconnection. */
104
- Object.defineProperty(this, "_onmessage", {
79
+ Object.defineProperty(this, "reconnectAbortController", {
105
80
  enumerable: true,
106
81
  configurable: true,
107
82
  writable: true,
108
- value: void 0
83
+ value: new AbortController()
109
84
  });
110
- /** WebSocket event handlers for reconnection. */
111
- Object.defineProperty(this, "_onopen", {
85
+ Object.defineProperty(this, "_open", {
112
86
  enumerable: true,
113
87
  configurable: true,
114
88
  writable: true,
115
- value: void 0
89
+ value: () => {
90
+ // Reset the attempt counter
91
+ this._attempt = 0;
92
+ // Send all buffered messages
93
+ let message;
94
+ while ((message = this.reconnectOptions.messageBuffer.shift()) !== undefined) {
95
+ this._socket.send(message);
96
+ }
97
+ }
116
98
  });
117
- /** Configuration options for WebSocket reconnection. */
118
- Object.defineProperty(this, "reconnectOptions", {
99
+ Object.defineProperty(this, "_close", {
119
100
  enumerable: true,
120
101
  configurable: true,
121
102
  writable: true,
122
- value: void 0
103
+ value: async (event) => {
104
+ try {
105
+ // If the event was triggered but the socket is not closing, ignore it
106
+ if (this._socket.readyState !== ReconnectingWebSocket.CLOSING &&
107
+ this._socket.readyState !== ReconnectingWebSocket.CLOSED)
108
+ return;
109
+ // If the instance is terminated, do not attempt to reconnect
110
+ if (this.reconnectAbortController.signal.aborted)
111
+ return;
112
+ // Check if reconnection should be attempted
113
+ if (++this._attempt > this.reconnectOptions.maxRetries) {
114
+ this._cleanup("RECONNECTION_LIMIT_REACHED");
115
+ return;
116
+ }
117
+ const userDecision = await this.reconnectOptions.shouldReconnect(event, this.reconnectAbortController.signal);
118
+ if (this.reconnectAbortController.signal.aborted)
119
+ return;
120
+ if (!userDecision) {
121
+ this._cleanup("RECONNECTION_STOPPED_BY_USER");
122
+ return;
123
+ }
124
+ // Delay before reconnecting
125
+ const reconnectDelay = typeof this.reconnectOptions.connectionDelay === "number"
126
+ ? this.reconnectOptions.connectionDelay
127
+ : await this.reconnectOptions.connectionDelay(this._attempt, this.reconnectAbortController.signal);
128
+ if (this.reconnectAbortController.signal.aborted)
129
+ return;
130
+ await delay(reconnectDelay, { signal: this.reconnectAbortController.signal });
131
+ // Create a new WebSocket instance
132
+ const { onclose, onerror, onmessage, onopen } = this._socket;
133
+ this._socket = this._createSocket(this._socket.url, this._protocols);
134
+ // Reconnect all listeners
135
+ this._setupEventListeners();
136
+ this._listeners.forEach(({ type, listenerProxy, options }) => {
137
+ this._socket.addEventListener(type, listenerProxy, options);
138
+ });
139
+ this._socket.onclose = onclose;
140
+ this._socket.onerror = onerror;
141
+ this._socket.onmessage = onmessage;
142
+ this._socket.onopen = onopen;
143
+ }
144
+ catch (error) {
145
+ this._cleanup("UNKNOWN_ERROR", error);
146
+ }
147
+ }
123
148
  });
124
- /** The signal that is aborted when the connection is permanently closed. */
125
- Object.defineProperty(this, "terminationSignal", {
149
+ Object.defineProperty(this, "CONNECTING", {
126
150
  enumerable: true,
127
151
  configurable: true,
128
152
  writable: true,
129
- value: this._terminationController.signal
153
+ value: 0
130
154
  });
131
- Object.defineProperty(this, "CLOSED", {
155
+ Object.defineProperty(this, "OPEN", {
132
156
  enumerable: true,
133
157
  configurable: true,
134
158
  writable: true,
135
- value: WebSocket.CLOSED
159
+ value: 1
136
160
  });
137
161
  Object.defineProperty(this, "CLOSING", {
138
162
  enumerable: true,
139
163
  configurable: true,
140
164
  writable: true,
141
- value: WebSocket.CLOSING
165
+ value: 2
142
166
  });
143
- Object.defineProperty(this, "CONNECTING", {
144
- enumerable: true,
145
- configurable: true,
146
- writable: true,
147
- value: WebSocket.CONNECTING
148
- });
149
- Object.defineProperty(this, "OPEN", {
167
+ Object.defineProperty(this, "CLOSED", {
150
168
  enumerable: true,
151
169
  configurable: true,
152
170
  writable: true,
153
- value: WebSocket.OPEN
171
+ value: 3
154
172
  });
155
- // Set the default options
156
173
  this.reconnectOptions = {
157
174
  maxRetries: options?.maxRetries ?? 3,
158
175
  connectionTimeout: options?.connectionTimeout === undefined ? 10_000 : options.connectionTimeout,
159
- connectionDelay: options?.connectionDelay ?? ((attempt) => Math.min(~~(1 << attempt) * 150, 10_000)),
176
+ connectionDelay: options?.connectionDelay ?? ((n) => Math.min(~~(1 << n) * 150, 10_000)),
160
177
  shouldReconnect: options?.shouldReconnect ?? (() => true),
161
178
  messageBuffer: options?.messageBuffer ?? new FIFOMessageBuffer(),
162
179
  };
180
+ this._socket = this._createSocket(url, protocols);
163
181
  this._protocols = protocols;
164
- // Create the WebSocket instance
165
- this._socket = createWebSocketWithTimeout(url, this._protocols, this.reconnectOptions.connectionTimeout);
166
- // Initialize the reconnection event listeners
167
- this._initEventListeners();
168
- // Store the original event listeners for reconnection
169
- this._onclose = this._socket.onclose;
170
- this._onerror = this._socket.onerror;
171
- this._onmessage = this._socket.onmessage;
172
- this._onopen = this._socket.onopen;
182
+ this._setupEventListeners();
173
183
  }
174
- /** Initializes the internal event listeners for the WebSocket. */
175
- _initEventListeners() {
176
- this._socket.addEventListener("open", () => {
177
- // Send all buffered messages
178
- let message;
179
- while ((message = this.reconnectOptions.messageBuffer.shift()) !== undefined) {
180
- this._socket.send(message);
181
- }
182
- }, { once: true });
183
- this._socket.addEventListener("close", async (event) => {
184
- try {
185
- // If the termination signal is already aborted, do not attempt to reconnect
186
- if (this._terminationController.signal.aborted)
187
- return;
188
- // Check if reconnection should be attempted
189
- if (++this._reconnectCount > this.reconnectOptions.maxRetries) {
190
- this._cleanup(new ReconnectingWebSocketError("RECONNECTION_LIMIT_REACHED"));
191
- return;
192
- }
193
- const userDecision = await this.reconnectOptions.shouldReconnect(event);
194
- if (this._terminationController.signal.aborted)
195
- return; // Check again after the await
196
- if (!userDecision) {
197
- this._cleanup(new ReconnectingWebSocketError("RECONNECTION_STOPPED_BY_USER"));
198
- return;
199
- }
200
- // Delay before reconnecting
201
- const delay = typeof this.reconnectOptions.connectionDelay === "number"
202
- ? this.reconnectOptions.connectionDelay
203
- : await this.reconnectOptions.connectionDelay(this._reconnectCount);
204
- if (this._terminationController.signal.aborted)
205
- return; // Check again after the await
206
- await sleep(delay, this._terminationController.signal);
207
- // Create a new WebSocket instance
208
- this._socket = createWebSocketWithTimeout(this.url, this._protocols, this.reconnectOptions.connectionTimeout);
209
- // Reconnect all listeners
210
- this._initEventListeners();
211
- this._eventListeners.forEach(({ type, listenerProxy, options }) => {
212
- this._socket.addEventListener(type, listenerProxy, options);
213
- });
214
- this._socket.onclose = this._onclose;
215
- this._socket.onerror = this._onerror;
216
- this._socket.onmessage = this._onmessage;
217
- this._socket.onopen = this._onopen;
218
- }
219
- catch (error) {
220
- this._cleanup(new ReconnectingWebSocketError("UNKNOWN_ERROR", error));
221
- }
222
- }, { once: true });
184
+ _createSocket(url, protocols) {
185
+ const socket = new WebSocket(url, protocols);
186
+ if (this.reconnectOptions.connectionTimeout === null)
187
+ return socket;
188
+ const timeoutId = setTimeout(() => {
189
+ socket.removeEventListener("open", openHandler);
190
+ socket.removeEventListener("close", closeHandler);
191
+ socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
192
+ }, this.reconnectOptions.connectionTimeout);
193
+ const openHandler = () => {
194
+ socket.removeEventListener("close", closeHandler);
195
+ clearTimeout(timeoutId);
196
+ };
197
+ const closeHandler = () => {
198
+ socket.removeEventListener("open", openHandler);
199
+ clearTimeout(timeoutId);
200
+ };
201
+ socket.addEventListener("open", openHandler, { once: true });
202
+ socket.addEventListener("close", closeHandler, { once: true });
203
+ return socket;
223
204
  }
224
- /**
225
- * Clean up internal resources.
226
- * @param reason - The reason for cleanup.
227
- */
228
- _cleanup(reason) {
229
- this._terminationController.abort(reason);
205
+ /** Initializes the internal event listeners for the socket. */
206
+ _setupEventListeners() {
207
+ this._socket.addEventListener("open", this._open, { once: true });
208
+ this._socket.addEventListener("close", this._close, { once: true });
209
+ }
210
+ /** Clean up internal resources. */
211
+ _cleanup(code, error) {
212
+ this.reconnectAbortController.abort(new ReconnectingWebSocketError(code, error));
230
213
  this.reconnectOptions.messageBuffer.clear();
231
- this._eventListeners = [];
232
- this._socket.dispatchEvent(new CustomEvent("error", { detail: reason }));
214
+ this._listeners = [];
215
+ this._socket.close();
233
216
  }
234
217
  // WebSocket property implementations
235
218
  get url() {
@@ -258,43 +241,38 @@ export class ReconnectingWebSocket {
258
241
  }
259
242
  set onclose(value) {
260
243
  this._socket.onclose = value;
261
- this._onclose = value; // Store the listener for reconnection
262
244
  }
263
245
  get onerror() {
264
246
  return this._socket.onerror;
265
247
  }
266
248
  set onerror(value) {
267
249
  this._socket.onerror = value;
268
- this._onerror = value; // Store the listener for reconnection
269
250
  }
270
251
  get onmessage() {
271
252
  return this._socket.onmessage;
272
253
  }
273
254
  set onmessage(value) {
274
255
  this._socket.onmessage = value;
275
- this._onmessage = value; // Store the listener for reconnection
276
256
  }
277
257
  get onopen() {
278
258
  return this._socket.onopen;
279
259
  }
280
260
  set onopen(value) {
281
261
  this._socket.onopen = value;
282
- this._onopen = value; // Store the listener for reconnection
283
262
  }
284
263
  /**
285
264
  * @param permanently - If `true`, the connection will be permanently closed. Default is `true`.
286
265
  */
287
266
  close(code, reason, permanently = true) {
288
267
  this._socket.close(code, reason);
289
- if (permanently) {
290
- this._cleanup(new ReconnectingWebSocketError("USER_INITIATED_CLOSE"));
291
- }
268
+ if (permanently)
269
+ this._cleanup("USER_INITIATED_CLOSE");
292
270
  }
293
271
  /**
294
272
  * @note If the connection is not open, the data will be buffered and sent when the connection is established.
295
273
  */
296
274
  send(data) {
297
- if (this._socket.readyState !== WebSocket.OPEN && !this._terminationController.signal.aborted) {
275
+ if (this._socket.readyState !== ReconnectingWebSocket.OPEN && !this.reconnectAbortController.signal.aborted) {
298
276
  this.reconnectOptions.messageBuffer.push(data);
299
277
  }
300
278
  else {
@@ -304,16 +282,16 @@ export class ReconnectingWebSocket {
304
282
  addEventListener(type, listener, options) {
305
283
  // Wrap the listener to handle reconnection
306
284
  let listenerProxy;
307
- if (this._terminationController.signal.aborted) {
308
- // If the connection is permanently closed, use the original listener
285
+ if (this.reconnectAbortController.signal.aborted) {
286
+ // If the instance is terminated, use the original listener
309
287
  listenerProxy = listener;
310
288
  }
311
289
  else {
312
290
  // Check if the listener is already registered
313
- const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
291
+ const index = this._listeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
314
292
  if (index !== -1) {
315
293
  // Use the existing listener proxy
316
- listenerProxy = this._eventListeners[index].listenerProxy;
294
+ listenerProxy = this._listeners[index].listenerProxy;
317
295
  }
318
296
  else {
319
297
  // Wrap the original listener to follow the once option when reconnecting
@@ -327,15 +305,16 @@ export class ReconnectingWebSocket {
327
305
  }
328
306
  }
329
307
  finally {
308
+ // If the listener is marked as once, remove it after the first invocation
330
309
  if (typeof options === "object" && options.once === true) {
331
- const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
310
+ const index = this._listeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
332
311
  if (index !== -1) {
333
- this._eventListeners.splice(index, 1);
312
+ this._listeners.splice(index, 1);
334
313
  }
335
314
  }
336
315
  }
337
316
  };
338
- this._eventListeners.push({ type, listener, options, listenerProxy });
317
+ this._listeners.push({ type, listener, options, listenerProxy });
339
318
  }
340
319
  }
341
320
  // Add the wrapped (or original) listener
@@ -343,11 +322,11 @@ export class ReconnectingWebSocket {
343
322
  }
344
323
  removeEventListener(type, listener, options) {
345
324
  // Remove a wrapped listener, not an original listener
346
- const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
325
+ const index = this._listeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
347
326
  if (index !== -1) {
348
- const { listenerProxy } = this._eventListeners[index];
327
+ const { listenerProxy } = this._listeners[index];
349
328
  this._socket.removeEventListener(type, listenerProxy, options);
350
- this._eventListeners.splice(index, 1);
329
+ this._listeners.splice(index, 1);
351
330
  }
352
331
  else {
353
332
  // If the wrapped listener is not found, remove the original listener
@@ -358,52 +337,30 @@ export class ReconnectingWebSocket {
358
337
  return this._socket.dispatchEvent(event);
359
338
  }
360
339
  }
361
- Object.defineProperty(ReconnectingWebSocket, "CLOSED", {
340
+ Object.defineProperty(ReconnectingWebSocket, "CONNECTING", {
362
341
  enumerable: true,
363
342
  configurable: true,
364
343
  writable: true,
365
- value: WebSocket.CLOSED
344
+ value: 0
366
345
  });
367
- Object.defineProperty(ReconnectingWebSocket, "CLOSING", {
346
+ Object.defineProperty(ReconnectingWebSocket, "OPEN", {
368
347
  enumerable: true,
369
348
  configurable: true,
370
349
  writable: true,
371
- value: WebSocket.CLOSING
350
+ value: 1
372
351
  });
373
- Object.defineProperty(ReconnectingWebSocket, "CONNECTING", {
352
+ Object.defineProperty(ReconnectingWebSocket, "CLOSING", {
374
353
  enumerable: true,
375
354
  configurable: true,
376
355
  writable: true,
377
- value: WebSocket.CONNECTING
356
+ value: 2
378
357
  });
379
- Object.defineProperty(ReconnectingWebSocket, "OPEN", {
358
+ Object.defineProperty(ReconnectingWebSocket, "CLOSED", {
380
359
  enumerable: true,
381
360
  configurable: true,
382
361
  writable: true,
383
- value: WebSocket.OPEN
362
+ value: 3
384
363
  });
385
- /** Creates a WebSocket with connection timeout. */
386
- function createWebSocketWithTimeout(url, protocols, timeout) {
387
- const socket = new WebSocket(url, protocols);
388
- if (timeout === null || timeout === undefined)
389
- return socket;
390
- const timeoutId = setTimeout(() => {
391
- socket.removeEventListener("open", openHandler);
392
- socket.removeEventListener("close", closeHandler);
393
- socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
394
- }, timeout);
395
- const openHandler = () => {
396
- socket.removeEventListener("close", closeHandler);
397
- clearTimeout(timeoutId);
398
- };
399
- const closeHandler = () => {
400
- socket.removeEventListener("open", openHandler);
401
- clearTimeout(timeoutId);
402
- };
403
- socket.addEventListener("open", openHandler, { once: true });
404
- socket.addEventListener("close", closeHandler, { once: true });
405
- return socket;
406
- }
407
364
  /** Check if two event listeners are the same (just like EventTarget). */
408
365
  function listenersMatch(a, b) {
409
366
  // EventTarget only compares capture in options, even if one is an object and the other is boolean
@@ -411,26 +368,3 @@ function listenersMatch(a, b) {
411
368
  const bCapture = Boolean(typeof b.options === "object" ? b.options.capture : b.options);
412
369
  return a.type === b.type && a.listener === b.listener && aCapture === bCapture;
413
370
  }
414
- /**
415
- * Returns a promise that resolves after the specified number of ms,
416
- * or rejects as soon as the given signal is aborted.
417
- * @param ms - The number of ms to sleep.
418
- * @param signal - An optional abort signal.
419
- * @returns A promise that resolves after the specified delay.
420
- */
421
- function sleep(ms, signal) {
422
- if (signal?.aborted)
423
- return Promise.reject(signal.reason);
424
- return new Promise((resolve, reject) => {
425
- const onAbort = () => {
426
- clearTimeout(timer);
427
- reject(signal?.reason);
428
- };
429
- const onTimeout = () => {
430
- signal?.removeEventListener("abort", onAbort);
431
- resolve();
432
- };
433
- const timer = setTimeout(onTimeout, ms);
434
- signal?.addEventListener("abort", onAbort, { once: true });
435
- });
436
- }
@@ -41,7 +41,7 @@ export interface WebSocketTransportOptions {
41
41
  reconnect?: ReconnectingWebSocketOptions;
42
42
  }
43
43
  /** WebSocket implementation of the REST and Subscription transport interfaces. */
44
- export declare class WebSocketTransport implements IRequestTransport, ISubscriptionTransport {
44
+ export declare class WebSocketTransport implements IRequestTransport, ISubscriptionTransport, AsyncDisposable {
45
45
  /** The interval timer ID for keep-alive messages. */
46
46
  protected _keepAliveTimer: number | null;
47
47
  /** The WebSocket request dispatcher instance. */
@@ -109,5 +109,12 @@ export declare class WebSocketTransport implements IRequestTransport, ISubscript
109
109
  * @returns A promise that resolves when the connection is fully closed.
110
110
  */
111
111
  close(signal?: AbortSignal): Promise<void>;
112
+ /**
113
+ * Combines the provided abort signal with the timeout signal.
114
+ * @param signal An optional abort signal.
115
+ * @returns A combined abort signal or undefined.
116
+ */
117
+ protected _getCombinedTimeoutSignal(signal?: AbortSignal): AbortSignal | undefined;
118
+ [Symbol.asyncDispose](): Promise<void>;
112
119
  }
113
120
  //# sourceMappingURL=websocket_transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocket_transport.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/websocket_transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,4BAA4B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AACvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,qBAAqB,EAAE,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAE,0BAA0B,EAAE,KAAK,4BAA4B,EAAE,CAAC;AAErG,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACtC;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE;QACR;;;;WAIG;QACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;IAEF;;OAEG;IACH,SAAS,CAAC,EAAE,4BAA4B,CAAC;CAC5C;AAED,kFAAkF;AAClF,qBAAa,kBAAmB,YAAW,iBAAiB,EAAE,sBAAsB;IAChF,qDAAqD;IACrD,SAAS,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,iDAAiD;IACjD,SAAS,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAEnD,6CAA6C;IAC7C,SAAS,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAE5C;;;;;OAKG;IACH,SAAS,CAAC,cAAc,EAAE,GAAG,CACzB,MAAM,EACN;QACI,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KACpC,CACJ,CAAa;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE;QAChB;;;WAGG;QACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,CAAC;IAEF,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAEvC;;;OAGG;gBACS,OAAO,CAAC,EAAE,yBAAyB;IAuC/C;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBzG;;;;;;;OAOG;IACG,SAAS,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,YAAY,CAAC;IAwExB;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB1C;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAoB7C"}
1
+ {"version":3,"file":"websocket_transport.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/websocket_transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,4BAA4B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AACvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,qBAAqB,EAAE,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAE,0BAA0B,EAAE,KAAK,4BAA4B,EAAE,CAAC;AAErG,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACtC;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE;QACR;;;;WAIG;QACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;IAEF;;OAEG;IACH,SAAS,CAAC,EAAE,4BAA4B,CAAC;CAC5C;AAED,kFAAkF;AAClF,qBAAa,kBAAmB,YAAW,iBAAiB,EAAE,sBAAsB,EAAE,eAAe;IACjG,qDAAqD;IACrD,SAAS,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,iDAAiD;IACjD,SAAS,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAEnD,6CAA6C;IAC7C,SAAS,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAE5C;;;;;OAKG;IACH,SAAS,CAAC,cAAc,EAAE,GAAG,CACzB,MAAM,EACN;QACI,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KACpC,CACJ,CAAa;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE;QAChB;;;WAGG;QACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,CAAC;IAEF,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAEvC;;;OAGG;gBACS,OAAO,CAAC,EAAE,yBAAyB;IAuC/C;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzG;;;;;;;OAOG;IACG,SAAS,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,YAAY,CAAC;IAgExB;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB1C;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB1C;;;;OAIG;IACH,SAAS,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS;IAQ5E,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/C"}
@@ -107,15 +107,11 @@ export class WebSocketTransport {
107
107
  * @note Explorer requests are not supported in the Hyperliquid WebSocket API.
108
108
  */
109
109
  request(type, payload, signal) {
110
- // Send the request and wait for a response
111
- const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
112
- const combinedSignal = signal && timeoutSignal
113
- ? AbortSignal.any([signal, timeoutSignal])
114
- : signal ?? timeoutSignal;
110
+ const combinedTimeoutSignal = this._getCombinedTimeoutSignal(signal);
115
111
  return this._wsRequester.request("post", {
116
112
  type: type === "exchange" ? "action" : type,
117
113
  payload,
118
- }, combinedSignal);
114
+ }, combinedTimeoutSignal);
119
115
  }
120
116
  /**
121
117
  * Subscribes to a Hyperliquid event channel.
@@ -132,11 +128,8 @@ export class WebSocketTransport {
132
128
  let subscription = this._subscriptions.get(id);
133
129
  if (!subscription) {
134
130
  // Send subscription request
135
- const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
136
- const combinedSignal = signal && timeoutSignal
137
- ? AbortSignal.any([signal, timeoutSignal])
138
- : signal ?? timeoutSignal;
139
- const requestPromise = this._wsRequester.request("subscribe", payload, combinedSignal);
131
+ const combinedTimeoutSignal = this._getCombinedTimeoutSignal(signal);
132
+ const requestPromise = this._wsRequester.request("subscribe", payload, combinedTimeoutSignal);
140
133
  // Cache subscription info
141
134
  subscription = { listeners: new Map(), requestPromise };
142
135
  this._subscriptions.set(id, subscription);
@@ -155,12 +148,9 @@ export class WebSocketTransport {
155
148
  // Cleanup subscription
156
149
  this._subscriptions.delete(id);
157
150
  // If the socket is open, send unsubscription request
158
- if (this.socket.readyState === WebSocket.OPEN) {
159
- const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
160
- const combinedSignal = signal && timeoutSignal
161
- ? AbortSignal.any([signal, timeoutSignal])
162
- : signal ?? timeoutSignal;
163
- await this._wsRequester.request("unsubscribe", payload, combinedSignal);
151
+ if (this.socket.readyState === ReconnectingWebSocket.OPEN) {
152
+ const combinedTimeoutSignal = this._getCombinedTimeoutSignal(signal);
153
+ await this._wsRequester.request("unsubscribe", payload, combinedTimeoutSignal);
164
154
  }
165
155
  }
166
156
  };
@@ -192,11 +182,11 @@ export class WebSocketTransport {
192
182
  ready(signal) {
193
183
  return new Promise((resolve, reject) => {
194
184
  const combinedSignal = signal
195
- ? AbortSignal.any([this.socket.terminationSignal, signal])
196
- : this.socket.terminationSignal;
185
+ ? AbortSignal.any([this.socket.reconnectAbortController.signal, signal])
186
+ : this.socket.reconnectAbortController.signal;
197
187
  if (combinedSignal.aborted)
198
188
  return reject(combinedSignal.reason);
199
- if (this.socket.readyState === WebSocket.OPEN)
189
+ if (this.socket.readyState === ReconnectingWebSocket.OPEN)
200
190
  return resolve();
201
191
  const handleOpen = () => {
202
192
  combinedSignal.removeEventListener("abort", handleAbort);
@@ -219,7 +209,7 @@ export class WebSocketTransport {
219
209
  return new Promise((resolve, reject) => {
220
210
  if (signal?.aborted)
221
211
  return reject(signal.reason);
222
- if (this.socket.readyState === WebSocket.CLOSED)
212
+ if (this.socket.readyState === ReconnectingWebSocket.CLOSED)
223
213
  return resolve();
224
214
  const handleClose = () => {
225
215
  signal?.removeEventListener("abort", handleAbort);
@@ -234,4 +224,19 @@ export class WebSocketTransport {
234
224
  this.socket.close();
235
225
  });
236
226
  }
227
+ /**
228
+ * Combines the provided abort signal with the timeout signal.
229
+ * @param signal An optional abort signal.
230
+ * @returns A combined abort signal or undefined.
231
+ */
232
+ _getCombinedTimeoutSignal(signal) {
233
+ const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
234
+ const combinedSignal = signal && timeoutSignal
235
+ ? AbortSignal.any([signal, timeoutSignal])
236
+ : signal ?? timeoutSignal;
237
+ return combinedSignal;
238
+ }
239
+ async [Symbol.asyncDispose]() {
240
+ await this.close();
241
+ }
237
242
  }