@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.
- package/README.md +5 -5
- package/esm/src/signing.d.ts +3 -3
- package/esm/src/signing.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.d.ts +2 -6
- package/esm/src/transports/http/http_transport.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.js +2 -4
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +22 -42
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/esm/src/transports/websocket/_reconnecting_websocket.js +133 -82
- package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts +6 -11
- package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -1
- package/esm/src/transports/websocket/_websocket_request_dispatcher.js +8 -12
- package/esm/src/transports/websocket/websocket_transport.d.ts +2 -4
- package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.js +14 -12
- package/package.json +1 -1
- package/script/src/signing.d.ts +3 -3
- package/script/src/signing.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.d.ts +2 -6
- package/script/src/transports/http/http_transport.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.js +2 -4
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts +22 -42
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/script/src/transports/websocket/_reconnecting_websocket.js +133 -82
- package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts +6 -11
- package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -1
- package/script/src/transports/websocket/_websocket_request_dispatcher.js +8 -12
- package/script/src/transports/websocket/websocket_transport.d.ts +2 -4
- package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- 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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
217
|
+
if (this._terminationController.signal.aborted)
|
|
212
218
|
return; // Check again after the await
|
|
213
|
-
await sleep(delay, this.
|
|
214
|
-
//
|
|
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
|
|
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.
|
|
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
|
-
//
|
|
316
|
-
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
/** Last used request ID */
|
|
18
|
-
|
|
16
|
+
private socket;
|
|
17
|
+
/** Last used post request ID */
|
|
18
|
+
private lastId;
|
|
19
19
|
/** Map of pending requests waiting for responses */
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
187
|
+
if (typeof obj === "string" && /^0x[0-9A-Fa-f]+$/.test(obj)) {
|
|
190
188
|
return obj.toLowerCase();
|
|
191
189
|
}
|
|
192
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
});
|