@nktkas/hyperliquid 0.15.1 → 0.15.2

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 (30) hide show
  1. package/README.md +5 -5
  2. package/esm/src/signing.d.ts +3 -3
  3. package/esm/src/signing.d.ts.map +1 -1
  4. package/esm/src/transports/http/http_transport.d.ts +2 -6
  5. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  6. package/esm/src/transports/http/http_transport.js +2 -4
  7. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +22 -42
  8. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  9. package/esm/src/transports/websocket/_reconnecting_websocket.js +133 -82
  10. package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts +6 -11
  11. package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -1
  12. package/esm/src/transports/websocket/_websocket_request_dispatcher.js +8 -12
  13. package/esm/src/transports/websocket/websocket_transport.d.ts +2 -4
  14. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  15. package/esm/src/transports/websocket/websocket_transport.js +14 -12
  16. package/package.json +1 -1
  17. package/script/src/signing.d.ts +3 -3
  18. package/script/src/signing.d.ts.map +1 -1
  19. package/script/src/transports/http/http_transport.d.ts +2 -6
  20. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  21. package/script/src/transports/http/http_transport.js +2 -4
  22. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +22 -42
  23. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  24. package/script/src/transports/websocket/_reconnecting_websocket.js +133 -82
  25. package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts +6 -11
  26. package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -1
  27. package/script/src/transports/websocket/_websocket_request_dispatcher.js +8 -12
  28. package/script/src/transports/websocket/websocket_transport.d.ts +2 -4
  29. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  30. package/script/src/transports/websocket/websocket_transport.js +14 -12
@@ -64,21 +64,21 @@
64
64
  * @param options - The configuration options.
65
65
  */
66
66
  constructor(url, protocols, options) {
67
- /** Controller for handling connection termination */
67
+ /** Controller for handling connection termination. */
68
68
  Object.defineProperty(this, "_terminationController", {
69
69
  enumerable: true,
70
70
  configurable: true,
71
71
  writable: true,
72
72
  value: new AbortController()
73
73
  });
74
- /** WebSocket protocols */
74
+ /** WebSocket protocols defined in constructor. */
75
75
  Object.defineProperty(this, "_protocols", {
76
76
  enumerable: true,
77
77
  configurable: true,
78
78
  writable: true,
79
79
  value: void 0
80
80
  });
81
- /** The underlying WebSocket instance */
81
+ /** Non-permanent original instance of WebSocket. */
82
82
  Object.defineProperty(this, "_socket", {
83
83
  enumerable: true,
84
84
  configurable: true,
@@ -92,21 +92,49 @@
92
92
  writable: true,
93
93
  value: 0
94
94
  });
95
- /** Array of registered event listeners */
95
+ /** The array of registered event listeners to recover from reconnection. */
96
96
  Object.defineProperty(this, "_eventListeners", {
97
97
  enumerable: true,
98
98
  configurable: true,
99
99
  writable: true,
100
100
  value: []
101
101
  });
102
- /** Configuration options */
102
+ /** WebSocket event handlers for reconnection. */
103
+ Object.defineProperty(this, "_onclose", {
104
+ enumerable: true,
105
+ configurable: true,
106
+ writable: true,
107
+ value: void 0
108
+ });
109
+ /** WebSocket event handlers for reconnection. */
110
+ Object.defineProperty(this, "_onerror", {
111
+ enumerable: true,
112
+ configurable: true,
113
+ writable: true,
114
+ value: void 0
115
+ });
116
+ /** WebSocket event handlers for reconnection. */
117
+ Object.defineProperty(this, "_onmessage", {
118
+ enumerable: true,
119
+ configurable: true,
120
+ writable: true,
121
+ value: void 0
122
+ });
123
+ /** WebSocket event handlers for reconnection. */
124
+ Object.defineProperty(this, "_onopen", {
125
+ enumerable: true,
126
+ configurable: true,
127
+ writable: true,
128
+ value: void 0
129
+ });
130
+ /** Configuration options for WebSocket reconnection. */
103
131
  Object.defineProperty(this, "reconnectOptions", {
104
132
  enumerable: true,
105
133
  configurable: true,
106
134
  writable: true,
107
135
  value: void 0
108
136
  });
109
- /** An AbortSignal that is triggered when the connection is permanently closed */
137
+ /** The signal that is aborted when the connection is permanently closed. */
110
138
  Object.defineProperty(this, "terminationSignal", {
111
139
  enumerable: true,
112
140
  configurable: true,
@@ -137,6 +165,7 @@
137
165
  writable: true,
138
166
  value: WebSocket.OPEN
139
167
  });
168
+ // Set the default options
140
169
  this.reconnectOptions = {
141
170
  maxRetries: options?.maxRetries ?? 3,
142
171
  connectionTimeout: options?.connectionTimeout === undefined ? 10_000 : options.connectionTimeout,
@@ -145,42 +174,19 @@
145
174
  messageBuffer: options?.messageBuffer ?? new FIFOMessageBuffer(),
146
175
  };
147
176
  this._protocols = protocols;
148
- this._socket = this.reconnectOptions.connectionTimeout
149
- ? this._connectWithTimeout(url, this._protocols, this.reconnectOptions.connectionTimeout)
150
- : new WebSocket(url, this._protocols);
177
+ // Create the WebSocket instance
178
+ this._socket = createWebSocketWithTimeout(url, this._protocols, this.reconnectOptions.connectionTimeout);
179
+ // Initialize the reconnection event listeners
151
180
  this._initEventListeners();
152
- }
153
- /**
154
- * Creates a WebSocket connection with timeout.
155
- * @param url - The WebSocket URL to connect to.
156
- * @param protocols - The WebSocket protocols to use.
157
- * @param timeout - The connection timeout in ms.
158
- * @returns A new WebSocket instance.
159
- */
160
- _connectWithTimeout(url, protocols, timeout) {
161
- const socket = new WebSocket(url, protocols);
162
- const timeoutId = setTimeout(() => {
163
- socket.removeEventListener("open", openHandler);
164
- socket.removeEventListener("close", closeHandler);
165
- socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
166
- }, timeout);
167
- const openHandler = () => {
168
- socket.removeEventListener("close", closeHandler);
169
- clearTimeout(timeoutId);
170
- };
171
- const closeHandler = () => {
172
- socket.removeEventListener("open", openHandler);
173
- clearTimeout(timeoutId);
174
- };
175
- socket.addEventListener("open", openHandler, { once: true });
176
- socket.addEventListener("close", closeHandler, { once: true });
177
- return socket;
181
+ // Store the original event listeners for reconnection
182
+ this._onclose = this._socket.onclose;
183
+ this._onerror = this._socket.onerror;
184
+ this._onmessage = this._socket.onmessage;
185
+ this._onopen = this._socket.onopen;
178
186
  }
179
187
  /** Initializes the internal event listeners for the WebSocket. */
180
188
  _initEventListeners() {
181
189
  this._socket.addEventListener("open", () => {
182
- // Reset reconnection count
183
- this._reconnectCount = 0;
184
190
  // Send all buffered messages
185
191
  let message;
186
192
  while ((message = this.reconnectOptions.messageBuffer.shift()) !== undefined) {
@@ -190,7 +196,7 @@
190
196
  this._socket.addEventListener("close", async (event) => {
191
197
  try {
192
198
  // If the termination signal is already aborted, do not attempt to reconnect
193
- if (this.terminationSignal.aborted)
199
+ if (this._terminationController.signal.aborted)
194
200
  return;
195
201
  // Check if reconnection should be attempted
196
202
  if (++this._reconnectCount > this.reconnectOptions.maxRetries) {
@@ -198,7 +204,7 @@
198
204
  return;
199
205
  }
200
206
  const userDecision = await this.reconnectOptions.shouldReconnect(event);
201
- if (this.terminationSignal.aborted)
207
+ if (this._terminationController.signal.aborted)
202
208
  return; // Check again after the await
203
209
  if (!userDecision) {
204
210
  this._cleanup(new ReconnectingWebSocketError("RECONNECTION_STOPPED_BY_USER"));
@@ -208,18 +214,20 @@
208
214
  const delay = typeof this.reconnectOptions.connectionDelay === "number"
209
215
  ? this.reconnectOptions.connectionDelay
210
216
  : await this.reconnectOptions.connectionDelay(this._reconnectCount);
211
- if (this.terminationSignal.aborted)
217
+ if (this._terminationController.signal.aborted)
212
218
  return; // Check again after the await
213
- await sleep(delay, this.terminationSignal);
214
- // Reconnect the socket
215
- this._socket = this.reconnectOptions.connectionTimeout
216
- ? this._connectWithTimeout(this.url, this._protocols, this.reconnectOptions.connectionTimeout)
217
- : new WebSocket(this.url, this._protocols);
219
+ await sleep(delay, this._terminationController.signal);
220
+ // Create a new WebSocket instance
221
+ this._socket = createWebSocketWithTimeout(this.url, this._protocols, this.reconnectOptions.connectionTimeout);
218
222
  // Reconnect all listeners
219
223
  this._initEventListeners();
220
224
  this._eventListeners.forEach(({ type, listenerProxy, options }) => {
221
225
  this._socket.addEventListener(type, listenerProxy, options);
222
226
  });
227
+ this._socket.onclose = this._onclose;
228
+ this._socket.onerror = this._onerror;
229
+ this._socket.onmessage = this._onmessage;
230
+ this._socket.onopen = this._onopen;
223
231
  }
224
232
  catch (error) {
225
233
  this._cleanup(new ReconnectingWebSocketError("UNKNOWN_ERROR", error));
@@ -234,17 +242,7 @@
234
242
  this._terminationController.abort(reason);
235
243
  this.reconnectOptions.messageBuffer.clear();
236
244
  this._eventListeners = [];
237
- }
238
- /**
239
- * Check if two event listeners are the same (just like EventTarget).
240
- * @param a - First event listener configuration.
241
- * @param b - Second event listener configuration.
242
- * @returns True if the listeners match.
243
- */
244
- _isListenerMatch(a, b) {
245
- const aCapture = Boolean(typeof a.options === "object" ? a.options.capture : a.options);
246
- const bCapture = Boolean(typeof b.options === "object" ? b.options.capture : b.options);
247
- return a.type === b.type && a.listener === b.listener && aCapture === bCapture;
245
+ this._socket.dispatchEvent(new CustomEvent("error", { detail: reason }));
248
246
  }
249
247
  // WebSocket property implementations
250
248
  get url() {
@@ -273,38 +271,43 @@
273
271
  }
274
272
  set onclose(value) {
275
273
  this._socket.onclose = value;
274
+ this._onclose = value; // Store the listener for reconnection
276
275
  }
277
276
  get onerror() {
278
277
  return this._socket.onerror;
279
278
  }
280
279
  set onerror(value) {
281
280
  this._socket.onerror = value;
281
+ this._onerror = value; // Store the listener for reconnection
282
282
  }
283
283
  get onmessage() {
284
284
  return this._socket.onmessage;
285
285
  }
286
286
  set onmessage(value) {
287
287
  this._socket.onmessage = value;
288
+ this._onmessage = value; // Store the listener for reconnection
288
289
  }
289
290
  get onopen() {
290
291
  return this._socket.onopen;
291
292
  }
292
293
  set onopen(value) {
293
294
  this._socket.onopen = value;
295
+ this._onopen = value; // Store the listener for reconnection
294
296
  }
295
297
  /**
296
- * @param permanently - If true, the connection will be permanently closed. Default is true.
298
+ * @param permanently - If `true`, the connection will be permanently closed. Default is `true`.
297
299
  */
298
300
  close(code, reason, permanently = true) {
299
- if (permanently)
300
- this._cleanup(new ReconnectingWebSocketError("USER_INITIATED_CLOSE"));
301
301
  this._socket.close(code, reason);
302
+ if (permanently) {
303
+ this._cleanup(new ReconnectingWebSocketError("USER_INITIATED_CLOSE"));
304
+ }
302
305
  }
303
306
  /**
304
307
  * @note If the connection is not open, the data will be buffered and sent when the connection is established.
305
308
  */
306
309
  send(data) {
307
- if (this._socket.readyState !== WebSocket.OPEN && !this.terminationSignal.aborted) {
310
+ if (this._socket.readyState !== WebSocket.OPEN && !this._terminationController.signal.aborted) {
308
311
  this.reconnectOptions.messageBuffer.push(data);
309
312
  }
310
313
  else {
@@ -312,38 +315,57 @@
312
315
  }
313
316
  }
314
317
  addEventListener(type, listener, options) {
315
- // Check if the listener is already added
316
- const exists = this._eventListeners.some((e) => this._isListenerMatch(e, { type, listener, options }));
317
- if (exists)
318
- return;
319
- // Wrap the original listener to follow the once option when reconnecting
320
- const listenerProxy = (event) => {
321
- try {
322
- if (typeof listener === "function") {
323
- listener.call(this, event);
324
- }
325
- else {
326
- listener.handleEvent(event);
327
- }
318
+ // Wrap the listener to handle reconnection
319
+ let listenerProxy;
320
+ if (this._terminationController.signal.aborted) {
321
+ // If the connection is permanently closed, use the original listener
322
+ listenerProxy = listener;
323
+ }
324
+ else {
325
+ // Check if the listener is already registered
326
+ const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
327
+ if (index !== -1) {
328
+ // Use the existing listener proxy
329
+ listenerProxy = this._eventListeners[index].listenerProxy;
328
330
  }
329
- finally {
330
- if (typeof options === "object" && options.once === true) {
331
- const index = this._eventListeners.findIndex((e) => this._isListenerMatch(e, { type, listener, options }));
332
- if (index !== -1)
333
- this._eventListeners.splice(index, 1);
334
- }
331
+ else {
332
+ // Wrap the original listener to follow the once option when reconnecting
333
+ listenerProxy = (event) => {
334
+ try {
335
+ if (typeof listener === "function") {
336
+ listener.call(this, event);
337
+ }
338
+ else {
339
+ listener.handleEvent(event);
340
+ }
341
+ }
342
+ finally {
343
+ if (typeof options === "object" && options.once === true) {
344
+ const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
345
+ if (index !== -1) {
346
+ this._eventListeners.splice(index, 1);
347
+ }
348
+ }
349
+ }
350
+ };
351
+ this._eventListeners.push({ type, listener, options, listenerProxy });
335
352
  }
336
- };
337
- this._eventListeners.push({ type, listener, options, listenerProxy });
353
+ }
354
+ // Add the wrapped (or original) listener
338
355
  this._socket.addEventListener(type, listenerProxy, options);
339
356
  }
340
357
  removeEventListener(type, listener, options) {
341
- const index = this._eventListeners.findIndex((e) => this._isListenerMatch(e, { type, listener, options }));
358
+ // Remove a wrapped listener, not an original listener
359
+ const index = this._eventListeners.findIndex((e) => listenersMatch(e, { type, listener, options }));
342
360
  if (index !== -1) {
343
361
  const { listenerProxy } = this._eventListeners[index];
344
362
  this._socket.removeEventListener(type, listenerProxy, options);
345
363
  this._eventListeners.splice(index, 1);
346
364
  }
365
+ else {
366
+ // If the wrapped listener is not found, remove the original listener
367
+ this._socket.removeEventListener(type, listener, options);
368
+ }
347
369
  }
348
370
  dispatchEvent(event) {
349
371
  return this._socket.dispatchEvent(event);
@@ -374,6 +396,35 @@
374
396
  writable: true,
375
397
  value: WebSocket.OPEN
376
398
  });
399
+ /** Creates a WebSocket with connection timeout. */
400
+ function createWebSocketWithTimeout(url, protocols, timeout) {
401
+ const socket = new WebSocket(url, protocols);
402
+ if (timeout === null || timeout === undefined)
403
+ return socket;
404
+ const timeoutId = setTimeout(() => {
405
+ socket.removeEventListener("open", openHandler);
406
+ socket.removeEventListener("close", closeHandler);
407
+ socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
408
+ }, timeout);
409
+ const openHandler = () => {
410
+ socket.removeEventListener("close", closeHandler);
411
+ clearTimeout(timeoutId);
412
+ };
413
+ const closeHandler = () => {
414
+ socket.removeEventListener("open", openHandler);
415
+ clearTimeout(timeoutId);
416
+ };
417
+ socket.addEventListener("open", openHandler, { once: true });
418
+ socket.addEventListener("close", closeHandler, { once: true });
419
+ return socket;
420
+ }
421
+ /** Check if two event listeners are the same (just like EventTarget). */
422
+ function listenersMatch(a, b) {
423
+ // EventTarget only compares capture in options, even if one is an object and the other is boolean
424
+ const aCapture = Boolean(typeof a.options === "object" ? a.options.capture : a.options);
425
+ const bCapture = Boolean(typeof b.options === "object" ? b.options.capture : b.options);
426
+ return a.type === b.type && a.listener === b.listener && aCapture === bCapture;
427
+ }
377
428
  /**
378
429
  * Returns a promise that resolves after the specified number of ms,
379
430
  * or rejects as soon as the given signal is aborted.
@@ -13,22 +13,17 @@ export declare class WebSocketRequestError extends TransportError {
13
13
  * Handles request creation, sending, and mapping responses to their corresponding requests.
14
14
  */
15
15
  export declare class WebSocketRequestDispatcher {
16
- protected socket: WebSocket;
17
- /** Last used request ID */
18
- protected lastId: number;
16
+ private socket;
17
+ /** Last used post request ID */
18
+ private lastId;
19
19
  /** Map of pending requests waiting for responses */
20
- protected pending: Map<number | string, {
21
- resolve: (value: unknown) => void;
22
- reject: (reason: unknown) => void;
23
- }>;
20
+ private pending;
24
21
  /**
25
22
  * Creates a new WebSocket request dispatcher.
26
23
  * @param socket - WebSocket connection instance for sending requests to the Hyperliquid WebSocket API
27
24
  * @param hlEvents - Used to recognize Hyperliquid responses and match them with sent requests
28
25
  */
29
26
  constructor(socket: WebSocket, hlEvents: HyperliquidEventTarget);
30
- /** Gets the next request ID */
31
- protected get nextId(): number;
32
27
  /**
33
28
  * Sends a request to the Hyperliquid API.
34
29
  * @param method - The method of websocket request.
@@ -42,13 +37,13 @@ export declare class WebSocketRequestDispatcher {
42
37
  * @param id - A request ID or a stringified request.
43
38
  * @param value - A resolution value.
44
39
  */
45
- protected resolve(id: number | string, value: unknown): void;
40
+ private resolve;
46
41
  /**
47
42
  * Rejects a pending request.
48
43
  * @param id - A request ID or a stringified request.
49
44
  * @param reason - A rejection reason.
50
45
  */
51
- protected reject(id: number | string, reason: unknown): void;
46
+ private reject;
52
47
  /**
53
48
  * Normalizes a request object to an ID.
54
49
  * @param value - A request object.
@@ -1 +1 @@
1
- {"version":3,"file":"_websocket_request_dispatcher.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/_websocket_request_dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;gBACzC,OAAO,EAAE,MAAM;CAI9B;AAED;;;GAGG;AACH,qBAAa,0BAA0B;IAevB,SAAS,CAAC,MAAM,EAAE,SAAS;IAdvC,2BAA2B;IAC3B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAE7B,oDAAoD;IACpD,SAAS,CAAC,OAAO,EAAE,GAAG,CAClB,MAAM,GAAG,MAAM,EACf;QAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAC3E,CAAa;IAEd;;;;OAIG;gBACmB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB;IA2DzE,+BAA+B;IAC/B,SAAS,KAAK,MAAM,IAAI,MAAM,CAE7B;IAED;;;;;;OAMG;IACG,OAAO,CACT,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,EAC5C,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,OAAO,CAAC;IAkCnB;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAK5D;;;;OAIG;IACH,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAK5D;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;CAK7C"}
1
+ {"version":3,"file":"_websocket_request_dispatcher.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/_websocket_request_dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAY7E;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;gBACzC,OAAO,EAAE,MAAM;CAI9B;AAED;;;GAGG;AACH,qBAAa,0BAA0B;IAkBvB,OAAO,CAAC,MAAM;IAjB1B,gCAAgC;IAChC,OAAO,CAAC,MAAM,CAAa;IAE3B,oDAAoD;IACpD,OAAO,CAAC,OAAO,CAMD;IAEd;;;;OAIG;gBACiB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB;IA2DvE;;;;;;OAMG;IACG,OAAO,CACT,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,EAC5C,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,OAAO,CAAC;IAiCnB;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAKf;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAKd;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;CAK7C"}
@@ -40,7 +40,7 @@
40
40
  writable: true,
41
41
  value: socket
42
42
  });
43
- /** Last used request ID */
43
+ /** Last used post request ID */
44
44
  Object.defineProperty(this, "lastId", {
45
45
  enumerable: true,
46
46
  configurable: true,
@@ -102,10 +102,6 @@
102
102
  this.pending.clear();
103
103
  });
104
104
  }
105
- /** Gets the next request ID */
106
- get nextId() {
107
- return ++this.lastId;
108
- }
109
105
  /**
110
106
  * Sends a request to the Hyperliquid API.
111
107
  * @param method - The method of websocket request.
@@ -114,12 +110,14 @@
114
110
  * @returns A promise that resolves with the parsed JSON response body.
115
111
  */
116
112
  async request(method, payload, signal) {
117
- signal?.throwIfAborted();
113
+ // Reject the request if the signal is aborted
114
+ if (signal?.aborted)
115
+ return Promise.reject(signal.reason);
118
116
  // Create a request object
119
117
  let id;
120
118
  let request;
121
119
  if (method === "post") {
122
- id = this.nextId;
120
+ id = ++this.lastId;
123
121
  request = { method, id, request: payload };
124
122
  }
125
123
  else {
@@ -180,18 +178,16 @@
180
178
  if (Array.isArray(obj)) {
181
179
  return obj.map(deepLowerHex);
182
180
  }
183
- else if (obj && typeof obj === "object") {
181
+ if (typeof obj === "object" && obj !== null) {
184
182
  return Object.entries(obj).reduce((acc, [key, val]) => ({
185
183
  ...acc,
186
184
  [key]: deepLowerHex(val),
187
185
  }), {});
188
186
  }
189
- else if (typeof obj === "string" && /^0x[0-9A-Fa-f]+$/.test(obj)) {
187
+ if (typeof obj === "string" && /^0x[0-9A-Fa-f]+$/.test(obj)) {
190
188
  return obj.toLowerCase();
191
189
  }
192
- else {
193
- return obj;
194
- }
190
+ return obj;
195
191
  }
196
192
  /**
197
193
  * Deeply sort the keys of an object.
@@ -1,9 +1,9 @@
1
- import { ReconnectingWebSocket, type ReconnectingWebSocketOptions } from "./_reconnecting_websocket.js";
1
+ import { type MessageBufferStrategy, ReconnectingWebSocket, ReconnectingWebSocketError, type ReconnectingWebSocketOptions } from "./_reconnecting_websocket.js";
2
2
  import { HyperliquidEventTarget } from "./_hyperliquid_event_target.js";
3
3
  import { WebSocketRequestDispatcher, WebSocketRequestError } from "./_websocket_request_dispatcher.js";
4
4
  import type { IRequestTransport, ISubscriptionTransport, Subscription } from "../../base.js";
5
5
  export { WebSocketRequestError };
6
- export type { MessageBufferStrategy, ReconnectingWebSocketOptions } from "./_reconnecting_websocket.js";
6
+ export { type MessageBufferStrategy, ReconnectingWebSocketError, type ReconnectingWebSocketOptions };
7
7
  /** Configuration options for the WebSocket transport layer. */
8
8
  export interface WebSocketTransportOptions {
9
9
  /**
@@ -105,7 +105,5 @@ export declare class WebSocketTransport implements IRequestTransport, ISubscript
105
105
  * @returns A promise that resolves when the connection is fully closed.
106
106
  */
107
107
  close(signal?: AbortSignal): Promise<void>;
108
- /** Combines a timeout with an optional abort signal. */
109
- protected _combineTimeoutWithSignal(timeout?: number | null, signal?: AbortSignal): AbortSignal | undefined;
110
108
  }
111
109
  //# 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,EAAE,qBAAqB,EAAE,KAAK,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AACxG,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,YAAY,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAExG,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACtC;;;;;OAKG;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;IAoBzG;;;;;;;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,wDAAwD;IACxD,SAAS,CAAC,yBAAyB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS;CAK9G"}
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;;;;;OAKG;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;IAwBzG;;;;;;;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"}
@@ -9,8 +9,9 @@
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.WebSocketTransport = exports.WebSocketRequestError = void 0;
12
+ exports.WebSocketTransport = exports.ReconnectingWebSocketError = exports.WebSocketRequestError = void 0;
13
13
  const _reconnecting_websocket_js_1 = require("./_reconnecting_websocket.js");
14
+ Object.defineProperty(exports, "ReconnectingWebSocketError", { enumerable: true, get: function () { return _reconnecting_websocket_js_1.ReconnectingWebSocketError; } });
14
15
  const _hyperliquid_event_target_js_1 = require("./_hyperliquid_event_target.js");
15
16
  const _websocket_request_dispatcher_js_1 = require("./_websocket_request_dispatcher.js");
16
17
  Object.defineProperty(exports, "WebSocketRequestError", { enumerable: true, get: function () { return _websocket_request_dispatcher_js_1.WebSocketRequestError; } });
@@ -123,7 +124,10 @@
123
124
  return Promise.reject(new _websocket_request_dispatcher_js_1.WebSocketRequestError("Explorer requests are not supported in the Hyperliquid WebSocket API."));
124
125
  }
125
126
  // Send the request and wait for a response
126
- const combinedSignal = this._combineTimeoutWithSignal(this.timeout, signal);
127
+ const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
128
+ const combinedSignal = signal && timeoutSignal
129
+ ? AbortSignal.any([signal, timeoutSignal])
130
+ : signal ?? timeoutSignal;
127
131
  return this._wsRequester.request("post", {
128
132
  type: type === "exchange" ? "action" : type,
129
133
  payload,
@@ -144,7 +148,10 @@
144
148
  let subscription = this._subscriptions.get(id);
145
149
  if (!subscription) {
146
150
  // Send subscription request
147
- const combinedSignal = this._combineTimeoutWithSignal(this.timeout, signal);
151
+ const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
152
+ const combinedSignal = signal && timeoutSignal
153
+ ? AbortSignal.any([signal, timeoutSignal])
154
+ : signal ?? timeoutSignal;
148
155
  const requestPromise = this._wsRequester.request("subscribe", payload, combinedSignal);
149
156
  // Cache subscription info
150
157
  subscription = { listeners: new Map(), requestPromise };
@@ -165,7 +172,10 @@
165
172
  this._subscriptions.delete(id);
166
173
  // If the socket is open, send unsubscription request
167
174
  if (this.socket.readyState === WebSocket.OPEN) {
168
- const combinedSignal = this._combineTimeoutWithSignal(this.timeout, signal);
175
+ const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
176
+ const combinedSignal = signal && timeoutSignal
177
+ ? AbortSignal.any([signal, timeoutSignal])
178
+ : signal ?? timeoutSignal;
169
179
  await this._wsRequester.request("unsubscribe", payload, combinedSignal);
170
180
  }
171
181
  }
@@ -240,14 +250,6 @@
240
250
  this.socket.close();
241
251
  });
242
252
  }
243
- /** Combines a timeout with an optional abort signal. */
244
- _combineTimeoutWithSignal(timeout, signal) {
245
- if (typeof timeout !== "number")
246
- return signal;
247
- if (!(signal instanceof AbortSignal))
248
- return AbortSignal.timeout(timeout);
249
- return AbortSignal.any([AbortSignal.timeout(timeout), signal]);
250
- }
251
253
  }
252
254
  exports.WebSocketTransport = WebSocketTransport;
253
255
  });