@nktkas/hyperliquid 0.19.2 → 0.20.0
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 +21 -29
- package/esm/_dnt.polyfills.d.ts +20 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +12 -0
- package/esm/mod.d.ts +3 -0
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +2 -0
- package/esm/src/base.d.ts +1 -47
- package/esm/src/base.d.ts.map +1 -1
- package/esm/src/base.js +1 -8
- package/esm/src/clients/event.d.ts +2 -3
- package/esm/src/clients/event.d.ts.map +1 -1
- package/esm/src/clients/event.js +49 -57
- package/esm/src/clients/public.d.ts +24 -5
- package/esm/src/clients/public.d.ts.map +1 -1
- package/esm/src/clients/public.js +23 -7
- package/esm/src/clients/wallet.d.ts +12 -13
- package/esm/src/clients/wallet.d.ts.map +1 -1
- package/esm/src/clients/wallet.js +55 -265
- package/esm/src/signing.d.ts +5 -0
- package/esm/src/signing.d.ts.map +1 -1
- package/esm/src/signing.js +24 -5
- package/esm/src/transports/base.d.ts +49 -0
- package/esm/src/transports/base.d.ts.map +1 -0
- package/esm/src/transports/base.js +8 -0
- package/esm/src/transports/http/http_transport.d.ts +8 -5
- package/esm/src/transports/http/http_transport.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.js +15 -62
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +36 -39
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +18 -25
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/esm/src/transports/websocket/_reconnecting_websocket.js +80 -179
- package/{script/src/transports/websocket/_websocket_request_dispatcher.d.ts → esm/src/transports/websocket/_websocket_async_request.d.ts} +14 -18
- package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -0
- package/esm/src/transports/websocket/{_websocket_request_dispatcher.js → _websocket_async_request.js} +41 -74
- package/esm/src/transports/websocket/websocket_transport.d.ts +38 -28
- package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.js +61 -76
- package/esm/src/types/info/assets.d.ts +0 -48
- package/esm/src/types/info/assets.d.ts.map +1 -1
- package/esm/src/types/info/markets.d.ts +52 -0
- package/esm/src/types/info/markets.d.ts.map +1 -0
- package/esm/src/types/info/markets.js +1 -0
- package/esm/src/types/info/requests.d.ts +9 -0
- package/esm/src/types/info/requests.d.ts.map +1 -1
- package/esm/src/types/mod.d.ts +4 -0
- package/esm/src/types/mod.d.ts.map +1 -1
- package/esm/src/types/mod.js +3 -1
- package/package.json +12 -9
- package/script/_dnt.polyfills.d.ts +20 -0
- package/script/_dnt.polyfills.d.ts.map +1 -0
- package/script/_dnt.polyfills.js +23 -0
- package/script/mod.d.ts +3 -0
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +3 -1
- package/script/src/base.d.ts +1 -47
- package/script/src/base.d.ts.map +1 -1
- package/script/src/base.js +2 -10
- package/script/src/clients/event.d.ts +2 -3
- package/script/src/clients/event.d.ts.map +1 -1
- package/script/src/clients/event.js +49 -57
- package/script/src/clients/public.d.ts +24 -5
- package/script/src/clients/public.d.ts.map +1 -1
- package/script/src/clients/public.js +23 -7
- package/script/src/clients/wallet.d.ts +12 -13
- package/script/src/clients/wallet.d.ts.map +1 -1
- package/script/src/clients/wallet.js +55 -265
- package/script/src/signing.d.ts +5 -0
- package/script/src/signing.d.ts.map +1 -1
- package/script/src/signing.js +75 -56
- package/script/src/transports/base.d.ts +49 -0
- package/script/src/transports/base.d.ts.map +1 -0
- package/script/src/transports/base.js +22 -0
- package/script/src/transports/http/http_transport.d.ts +8 -5
- package/script/src/transports/http/http_transport.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.js +16 -63
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +36 -39
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts +18 -25
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/script/src/transports/websocket/_reconnecting_websocket.js +81 -180
- package/{esm/src/transports/websocket/_websocket_request_dispatcher.d.ts → script/src/transports/websocket/_websocket_async_request.d.ts} +14 -18
- package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -0
- package/script/src/transports/websocket/{_websocket_request_dispatcher.js → _websocket_async_request.js} +44 -77
- package/script/src/transports/websocket/websocket_transport.d.ts +38 -28
- package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/script/src/transports/websocket/websocket_transport.js +63 -78
- package/script/src/types/info/assets.d.ts +0 -48
- package/script/src/types/info/assets.d.ts.map +1 -1
- package/script/src/types/info/markets.d.ts +52 -0
- package/script/src/types/info/markets.d.ts.map +1 -0
- package/script/{deps/jsr.io/@noble/hashes/1.8.0/src/crypto.js → src/types/info/markets.js} +0 -2
- package/script/src/types/info/requests.d.ts +9 -0
- package/script/src/types/info/requests.d.ts.map +1 -1
- package/script/src/types/mod.d.ts +4 -0
- package/script/src/types/mod.d.ts.map +1 -1
- package/script/src/types/mod.js +25 -22
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts +0 -55
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts.map +0 -1
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.js +0 -66
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts +0 -2
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts.map +0 -1
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.js +0 -1
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts +0 -53
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts.map +0 -1
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.js +0 -294
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts +0 -161
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts.map +0 -1
- package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.js +0 -280
- package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +0 -1
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts +0 -55
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts.map +0 -1
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.js +0 -99
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts +0 -2
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts.map +0 -1
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts +0 -53
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts.map +0 -1
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.js +0 -309
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts +0 -161
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts.map +0 -1
- package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.js +0 -322
- package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +0 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "../../../deps/jsr.io/@std/async/1.0.13/delay.js", "
|
|
7
|
+
define(["require", "exports", "../../../deps/jsr.io/@std/async/1.0.13/delay.js", "../base.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
@@ -12,44 +12,27 @@
|
|
|
12
12
|
exports.ReconnectingWebSocket = exports.ReconnectingWebSocketError = void 0;
|
|
13
13
|
// deno-lint-ignore-file no-explicit-any
|
|
14
14
|
const delay_js_1 = require("../../../deps/jsr.io/@std/async/1.0.13/delay.js");
|
|
15
|
-
const base_js_1 = require("
|
|
15
|
+
const base_js_1 = require("../base.js");
|
|
16
16
|
/** Simple FIFO (First In, First Out) buffer implementation. */
|
|
17
17
|
class FIFOMessageBuffer {
|
|
18
|
-
|
|
19
|
-
Object.defineProperty(this, "messages", {
|
|
20
|
-
enumerable: true,
|
|
21
|
-
configurable: true,
|
|
22
|
-
writable: true,
|
|
23
|
-
value: []
|
|
24
|
-
});
|
|
25
|
-
}
|
|
18
|
+
queue = [];
|
|
26
19
|
push(data) {
|
|
27
|
-
this.
|
|
28
|
-
}
|
|
29
|
-
shift() {
|
|
30
|
-
return this.messages.shift();
|
|
20
|
+
this.queue.push(data);
|
|
31
21
|
}
|
|
32
|
-
|
|
33
|
-
this.
|
|
22
|
+
*[Symbol.iterator]() {
|
|
23
|
+
while (this.queue.length > 0) {
|
|
24
|
+
yield this.queue.shift();
|
|
25
|
+
}
|
|
34
26
|
}
|
|
35
27
|
}
|
|
36
28
|
/** Error thrown when reconnection problems occur. */
|
|
37
29
|
class ReconnectingWebSocketError extends base_js_1.TransportError {
|
|
38
|
-
|
|
30
|
+
code;
|
|
31
|
+
constructor(code, cause) {
|
|
39
32
|
super(`Error when reconnecting WebSocket: ${code}`);
|
|
40
|
-
|
|
41
|
-
enumerable: true,
|
|
42
|
-
configurable: true,
|
|
43
|
-
writable: true,
|
|
44
|
-
value: code
|
|
45
|
-
});
|
|
46
|
-
Object.defineProperty(this, "originalError", {
|
|
47
|
-
enumerable: true,
|
|
48
|
-
configurable: true,
|
|
49
|
-
writable: true,
|
|
50
|
-
value: originalError
|
|
51
|
-
});
|
|
33
|
+
this.code = code;
|
|
52
34
|
this.name = "ReconnectingWebSocketError";
|
|
35
|
+
this.cause = cause;
|
|
53
36
|
}
|
|
54
37
|
}
|
|
55
38
|
exports.ReconnectingWebSocketError = ReconnectingWebSocketError;
|
|
@@ -58,131 +41,13 @@
|
|
|
58
41
|
* Fully compatible with standard WebSocket API.
|
|
59
42
|
*/
|
|
60
43
|
class ReconnectingWebSocket {
|
|
44
|
+
_socket;
|
|
45
|
+
_protocols;
|
|
46
|
+
_listeners = [];
|
|
47
|
+
_attempt = 0;
|
|
48
|
+
reconnectOptions;
|
|
49
|
+
reconnectAbortController = new AbortController();
|
|
61
50
|
constructor(url, protocols, options) {
|
|
62
|
-
Object.defineProperty(this, "_socket", {
|
|
63
|
-
enumerable: true,
|
|
64
|
-
configurable: true,
|
|
65
|
-
writable: true,
|
|
66
|
-
value: void 0
|
|
67
|
-
});
|
|
68
|
-
Object.defineProperty(this, "_protocols", {
|
|
69
|
-
enumerable: true,
|
|
70
|
-
configurable: true,
|
|
71
|
-
writable: true,
|
|
72
|
-
value: void 0
|
|
73
|
-
});
|
|
74
|
-
Object.defineProperty(this, "_listeners", {
|
|
75
|
-
enumerable: true,
|
|
76
|
-
configurable: true,
|
|
77
|
-
writable: true,
|
|
78
|
-
value: []
|
|
79
|
-
});
|
|
80
|
-
Object.defineProperty(this, "_attempt", {
|
|
81
|
-
enumerable: true,
|
|
82
|
-
configurable: true,
|
|
83
|
-
writable: true,
|
|
84
|
-
value: 0
|
|
85
|
-
});
|
|
86
|
-
Object.defineProperty(this, "reconnectOptions", {
|
|
87
|
-
enumerable: true,
|
|
88
|
-
configurable: true,
|
|
89
|
-
writable: true,
|
|
90
|
-
value: void 0
|
|
91
|
-
});
|
|
92
|
-
Object.defineProperty(this, "reconnectAbortController", {
|
|
93
|
-
enumerable: true,
|
|
94
|
-
configurable: true,
|
|
95
|
-
writable: true,
|
|
96
|
-
value: new AbortController()
|
|
97
|
-
});
|
|
98
|
-
Object.defineProperty(this, "_open", {
|
|
99
|
-
enumerable: true,
|
|
100
|
-
configurable: true,
|
|
101
|
-
writable: true,
|
|
102
|
-
value: () => {
|
|
103
|
-
// Reset the attempt counter
|
|
104
|
-
this._attempt = 0;
|
|
105
|
-
// Send all buffered messages
|
|
106
|
-
let message;
|
|
107
|
-
while ((message = this.reconnectOptions.messageBuffer.shift()) !== undefined) {
|
|
108
|
-
this._socket.send(message);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
Object.defineProperty(this, "_close", {
|
|
113
|
-
enumerable: true,
|
|
114
|
-
configurable: true,
|
|
115
|
-
writable: true,
|
|
116
|
-
value: async (event) => {
|
|
117
|
-
try {
|
|
118
|
-
// If the event was triggered but the socket is not closing, ignore it
|
|
119
|
-
if (this._socket.readyState !== ReconnectingWebSocket.CLOSING &&
|
|
120
|
-
this._socket.readyState !== ReconnectingWebSocket.CLOSED)
|
|
121
|
-
return;
|
|
122
|
-
// If the instance is terminated, do not attempt to reconnect
|
|
123
|
-
if (this.reconnectAbortController.signal.aborted)
|
|
124
|
-
return;
|
|
125
|
-
// Check if reconnection should be attempted
|
|
126
|
-
if (++this._attempt > this.reconnectOptions.maxRetries) {
|
|
127
|
-
this._cleanup("RECONNECTION_LIMIT_REACHED");
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const userDecision = await this.reconnectOptions.shouldReconnect(event, this.reconnectAbortController.signal);
|
|
131
|
-
if (this.reconnectAbortController.signal.aborted)
|
|
132
|
-
return;
|
|
133
|
-
if (!userDecision) {
|
|
134
|
-
this._cleanup("RECONNECTION_STOPPED_BY_USER");
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
// Delay before reconnecting
|
|
138
|
-
const reconnectDelay = typeof this.reconnectOptions.connectionDelay === "number"
|
|
139
|
-
? this.reconnectOptions.connectionDelay
|
|
140
|
-
: await this.reconnectOptions.connectionDelay(this._attempt, this.reconnectAbortController.signal);
|
|
141
|
-
if (this.reconnectAbortController.signal.aborted)
|
|
142
|
-
return;
|
|
143
|
-
await (0, delay_js_1.delay)(reconnectDelay, { signal: this.reconnectAbortController.signal });
|
|
144
|
-
// Create a new WebSocket instance
|
|
145
|
-
const { onclose, onerror, onmessage, onopen } = this._socket;
|
|
146
|
-
this._socket = this._createSocket(this._socket.url, this._protocols);
|
|
147
|
-
// Reconnect all listeners
|
|
148
|
-
this._setupEventListeners();
|
|
149
|
-
this._listeners.forEach(({ type, listenerProxy, options }) => {
|
|
150
|
-
this._socket.addEventListener(type, listenerProxy, options);
|
|
151
|
-
});
|
|
152
|
-
this._socket.onclose = onclose;
|
|
153
|
-
this._socket.onerror = onerror;
|
|
154
|
-
this._socket.onmessage = onmessage;
|
|
155
|
-
this._socket.onopen = onopen;
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
this._cleanup("UNKNOWN_ERROR", error);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
Object.defineProperty(this, "CONNECTING", {
|
|
163
|
-
enumerable: true,
|
|
164
|
-
configurable: true,
|
|
165
|
-
writable: true,
|
|
166
|
-
value: 0
|
|
167
|
-
});
|
|
168
|
-
Object.defineProperty(this, "OPEN", {
|
|
169
|
-
enumerable: true,
|
|
170
|
-
configurable: true,
|
|
171
|
-
writable: true,
|
|
172
|
-
value: 1
|
|
173
|
-
});
|
|
174
|
-
Object.defineProperty(this, "CLOSING", {
|
|
175
|
-
enumerable: true,
|
|
176
|
-
configurable: true,
|
|
177
|
-
writable: true,
|
|
178
|
-
value: 2
|
|
179
|
-
});
|
|
180
|
-
Object.defineProperty(this, "CLOSED", {
|
|
181
|
-
enumerable: true,
|
|
182
|
-
configurable: true,
|
|
183
|
-
writable: true,
|
|
184
|
-
value: 3
|
|
185
|
-
});
|
|
186
51
|
this.reconnectOptions = {
|
|
187
52
|
maxRetries: options?.maxRetries ?? 3,
|
|
188
53
|
connectionTimeout: options?.connectionTimeout === undefined ? 10_000 : options.connectionTimeout,
|
|
@@ -220,10 +85,62 @@
|
|
|
220
85
|
this._socket.addEventListener("open", this._open, { once: true });
|
|
221
86
|
this._socket.addEventListener("close", this._close, { once: true });
|
|
222
87
|
}
|
|
88
|
+
_open = () => {
|
|
89
|
+
// Reset the attempt counter
|
|
90
|
+
this._attempt = 0;
|
|
91
|
+
// Send all buffered messages
|
|
92
|
+
for (const message of this.reconnectOptions.messageBuffer) {
|
|
93
|
+
this._socket.send(message);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
_close = async (event) => {
|
|
97
|
+
try {
|
|
98
|
+
// If the event was triggered but the socket is not closing, ignore it
|
|
99
|
+
if (this._socket.readyState !== ReconnectingWebSocket.CLOSING &&
|
|
100
|
+
this._socket.readyState !== ReconnectingWebSocket.CLOSED)
|
|
101
|
+
return;
|
|
102
|
+
// If the instance is terminated, do not attempt to reconnect
|
|
103
|
+
if (this.reconnectAbortController.signal.aborted)
|
|
104
|
+
return;
|
|
105
|
+
// Check if reconnection should be attempted
|
|
106
|
+
if (++this._attempt > this.reconnectOptions.maxRetries) {
|
|
107
|
+
this._cleanup("RECONNECTION_LIMIT_REACHED");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const userDecision = await this.reconnectOptions.shouldReconnect(event, this.reconnectAbortController.signal);
|
|
111
|
+
if (this.reconnectAbortController.signal.aborted)
|
|
112
|
+
return;
|
|
113
|
+
if (!userDecision) {
|
|
114
|
+
this._cleanup("RECONNECTION_STOPPED_BY_USER");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// Delay before reconnecting
|
|
118
|
+
const reconnectDelay = typeof this.reconnectOptions.connectionDelay === "number"
|
|
119
|
+
? this.reconnectOptions.connectionDelay
|
|
120
|
+
: await this.reconnectOptions.connectionDelay(this._attempt, this.reconnectAbortController.signal);
|
|
121
|
+
if (this.reconnectAbortController.signal.aborted)
|
|
122
|
+
return;
|
|
123
|
+
await (0, delay_js_1.delay)(reconnectDelay, { signal: this.reconnectAbortController.signal });
|
|
124
|
+
// Create a new WebSocket instance
|
|
125
|
+
const { onclose, onerror, onmessage, onopen } = this._socket;
|
|
126
|
+
this._socket = this._createSocket(this._socket.url, this._protocols);
|
|
127
|
+
// Reconnect all listeners
|
|
128
|
+
this._setupEventListeners();
|
|
129
|
+
this._listeners.forEach(({ type, listenerProxy, options }) => {
|
|
130
|
+
this._socket.addEventListener(type, listenerProxy, options);
|
|
131
|
+
});
|
|
132
|
+
this._socket.onclose = onclose;
|
|
133
|
+
this._socket.onerror = onerror;
|
|
134
|
+
this._socket.onmessage = onmessage;
|
|
135
|
+
this._socket.onopen = onopen;
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this._cleanup("UNKNOWN_ERROR", error);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
223
141
|
/** Clean up internal resources. */
|
|
224
|
-
_cleanup(code,
|
|
225
|
-
this.reconnectAbortController.abort(new ReconnectingWebSocketError(code,
|
|
226
|
-
this.reconnectOptions.messageBuffer.clear();
|
|
142
|
+
_cleanup(code, cause) {
|
|
143
|
+
this.reconnectAbortController.abort(new ReconnectingWebSocketError(code, cause));
|
|
227
144
|
this._listeners = [];
|
|
228
145
|
this._socket.close();
|
|
229
146
|
}
|
|
@@ -249,6 +166,14 @@
|
|
|
249
166
|
set binaryType(value) {
|
|
250
167
|
this._socket.binaryType = value;
|
|
251
168
|
}
|
|
169
|
+
CONNECTING = 0;
|
|
170
|
+
OPEN = 1;
|
|
171
|
+
CLOSING = 2;
|
|
172
|
+
CLOSED = 3;
|
|
173
|
+
static CONNECTING = 0;
|
|
174
|
+
static OPEN = 1;
|
|
175
|
+
static CLOSING = 2;
|
|
176
|
+
static CLOSED = 3;
|
|
252
177
|
get onclose() {
|
|
253
178
|
return this._socket.onclose;
|
|
254
179
|
}
|
|
@@ -351,30 +276,6 @@
|
|
|
351
276
|
}
|
|
352
277
|
}
|
|
353
278
|
exports.ReconnectingWebSocket = ReconnectingWebSocket;
|
|
354
|
-
Object.defineProperty(ReconnectingWebSocket, "CONNECTING", {
|
|
355
|
-
enumerable: true,
|
|
356
|
-
configurable: true,
|
|
357
|
-
writable: true,
|
|
358
|
-
value: 0
|
|
359
|
-
});
|
|
360
|
-
Object.defineProperty(ReconnectingWebSocket, "OPEN", {
|
|
361
|
-
enumerable: true,
|
|
362
|
-
configurable: true,
|
|
363
|
-
writable: true,
|
|
364
|
-
value: 1
|
|
365
|
-
});
|
|
366
|
-
Object.defineProperty(ReconnectingWebSocket, "CLOSING", {
|
|
367
|
-
enumerable: true,
|
|
368
|
-
configurable: true,
|
|
369
|
-
writable: true,
|
|
370
|
-
value: 2
|
|
371
|
-
});
|
|
372
|
-
Object.defineProperty(ReconnectingWebSocket, "CLOSED", {
|
|
373
|
-
enumerable: true,
|
|
374
|
-
configurable: true,
|
|
375
|
-
writable: true,
|
|
376
|
-
value: 3
|
|
377
|
-
});
|
|
378
279
|
/** Check if two event listeners are the same (just like EventTarget). */
|
|
379
280
|
function listenersMatch(a, b) {
|
|
380
281
|
// EventTarget only compares capture in options, even if one is an object and the other is boolean
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TransportError } from "
|
|
1
|
+
import { TransportError } from "../base.js";
|
|
2
2
|
import type { HyperliquidEventTarget } from "./_hyperliquid_event_target.js";
|
|
3
3
|
/**
|
|
4
4
|
* Error thrown when a WebSocket request fails:
|
|
@@ -12,31 +12,27 @@ export declare class WebSocketRequestError extends TransportError {
|
|
|
12
12
|
* Manages WebSocket requests to the Hyperliquid API.
|
|
13
13
|
* Handles request creation, sending, and mapping responses to their corresponding requests.
|
|
14
14
|
*/
|
|
15
|
-
export declare class
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
export declare class WebSocketAsyncRequest {
|
|
16
|
+
protected socket: WebSocket;
|
|
17
|
+
protected lastId: number;
|
|
18
|
+
protected queue: Map<number | string, {
|
|
19
|
+
resolve: (value?: any) => void;
|
|
20
|
+
reject: (reason?: any) => void;
|
|
21
|
+
}>;
|
|
22
|
+
lastRequestTime: number;
|
|
21
23
|
/**
|
|
22
|
-
* Creates a new WebSocket request
|
|
24
|
+
* Creates a new WebSocket async request handler.
|
|
23
25
|
* @param socket - WebSocket connection instance for sending requests to the Hyperliquid WebSocket API
|
|
24
26
|
* @param hlEvents - Used to recognize Hyperliquid responses and match them with sent requests
|
|
25
27
|
*/
|
|
26
28
|
constructor(socket: WebSocket, hlEvents: HyperliquidEventTarget);
|
|
27
29
|
/**
|
|
28
30
|
* Sends a request to the Hyperliquid API.
|
|
29
|
-
* @param method - The method of websocket request.
|
|
30
|
-
* @param payload - The payload to send with the request.
|
|
31
|
-
* @param signal - An optional abort signal.
|
|
32
31
|
* @returns A promise that resolves with the parsed JSON response body.
|
|
33
32
|
*/
|
|
34
|
-
request(method: "
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* @param value - A request object.
|
|
38
|
-
* @returns A stringified request.
|
|
39
|
-
*/
|
|
33
|
+
request(method: "ping", signal?: AbortSignal): Promise<void>;
|
|
34
|
+
request<T>(method: "post" | "subscribe" | "unsubscribe", payload: unknown, signal?: AbortSignal): Promise<T>;
|
|
35
|
+
/** Normalizes an object and then converts it to a string. */
|
|
40
36
|
static requestToId(value: unknown): string;
|
|
41
37
|
}
|
|
42
|
-
//# sourceMappingURL=
|
|
38
|
+
//# sourceMappingURL=_websocket_async_request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_websocket_async_request.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/_websocket_async_request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAiB7E;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;gBACzC,OAAO,EAAE,MAAM;CAI9B;AAED;;;GAGG;AACH,qBAAa,qBAAqB;IAkBlB,SAAS,CAAC,MAAM,EAAE,SAAS;IAjBvC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAC7B,SAAS,CAAC,KAAK,EAAE,GAAG,CAChB,MAAM,GAAG,MAAM,EACf;QAEI,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;QAE/B,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;KAClC,CACJ,CAAa;IACd,eAAe,EAAE,MAAM,CAAK;IAE5B;;;;OAIG;gBACmB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB;IA2DzE;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAC5D,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IA2ClH,6DAA6D;IAC7D,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;CAK7C"}
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "
|
|
7
|
+
define(["require", "exports", "../base.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
const base_js_1 = require("
|
|
12
|
+
exports.WebSocketAsyncRequest = exports.WebSocketRequestError = void 0;
|
|
13
|
+
const base_js_1 = require("../base.js");
|
|
14
14
|
/**
|
|
15
15
|
* Error thrown when a WebSocket request fails:
|
|
16
16
|
* - When the WebSocket connection is closed
|
|
@@ -27,44 +27,32 @@
|
|
|
27
27
|
* Manages WebSocket requests to the Hyperliquid API.
|
|
28
28
|
* Handles request creation, sending, and mapping responses to their corresponding requests.
|
|
29
29
|
*/
|
|
30
|
-
class
|
|
30
|
+
class WebSocketAsyncRequest {
|
|
31
|
+
socket;
|
|
32
|
+
lastId = 0;
|
|
33
|
+
queue = new Map();
|
|
34
|
+
lastRequestTime = 0;
|
|
31
35
|
/**
|
|
32
|
-
* Creates a new WebSocket request
|
|
36
|
+
* Creates a new WebSocket async request handler.
|
|
33
37
|
* @param socket - WebSocket connection instance for sending requests to the Hyperliquid WebSocket API
|
|
34
38
|
* @param hlEvents - Used to recognize Hyperliquid responses and match them with sent requests
|
|
35
39
|
*/
|
|
36
40
|
constructor(socket, hlEvents) {
|
|
37
|
-
|
|
38
|
-
enumerable: true,
|
|
39
|
-
configurable: true,
|
|
40
|
-
writable: true,
|
|
41
|
-
value: socket
|
|
42
|
-
});
|
|
43
|
-
/** Last used post request ID */
|
|
44
|
-
Object.defineProperty(this, "lastId", {
|
|
45
|
-
enumerable: true,
|
|
46
|
-
configurable: true,
|
|
47
|
-
writable: true,
|
|
48
|
-
value: 0
|
|
49
|
-
});
|
|
50
|
-
/** Map of pending requests waiting for responses */
|
|
51
|
-
Object.defineProperty(this, "pending", {
|
|
52
|
-
enumerable: true,
|
|
53
|
-
configurable: true,
|
|
54
|
-
writable: true,
|
|
55
|
-
value: new Map()
|
|
56
|
-
});
|
|
41
|
+
this.socket = socket;
|
|
57
42
|
// Monitor responses and match the pending request
|
|
58
43
|
hlEvents.addEventListener("subscriptionResponse", (event) => {
|
|
59
44
|
// Use a stringified request as an id
|
|
60
|
-
const id =
|
|
61
|
-
this.
|
|
45
|
+
const id = WebSocketAsyncRequest.requestToId(event.detail.subscription);
|
|
46
|
+
this.queue.get(id)?.resolve(event.detail);
|
|
62
47
|
});
|
|
63
48
|
hlEvents.addEventListener("post", (event) => {
|
|
64
49
|
const data = event.detail.response.type === "info"
|
|
65
50
|
? event.detail.response.payload.data
|
|
66
51
|
: event.detail.response.payload;
|
|
67
|
-
this.
|
|
52
|
+
this.queue.get(event.detail.id)?.resolve(data);
|
|
53
|
+
});
|
|
54
|
+
hlEvents.addEventListener("pong", () => {
|
|
55
|
+
this.queue.get("ping")?.resolve();
|
|
68
56
|
});
|
|
69
57
|
hlEvents.addEventListener("error", (event) => {
|
|
70
58
|
try {
|
|
@@ -74,19 +62,19 @@
|
|
|
74
62
|
const parsedRequest = JSON.parse(request);
|
|
75
63
|
if ("id" in parsedRequest && typeof parsedRequest.id === "number") {
|
|
76
64
|
// If a post request was sent, it is possible to get the id from the request
|
|
77
|
-
this.
|
|
65
|
+
this.queue.get(parsedRequest.id)?.reject(new WebSocketRequestError(`Cannot complete WebSocket request: ${event.detail}`));
|
|
78
66
|
}
|
|
79
67
|
else if ("subscription" in parsedRequest &&
|
|
80
68
|
typeof parsedRequest.subscription === "object" &&
|
|
81
69
|
parsedRequest.subscription !== null) {
|
|
82
70
|
// If a subscription/unsubscribe request was sent, use the request as an id
|
|
83
|
-
const id =
|
|
84
|
-
this.
|
|
71
|
+
const id = WebSocketAsyncRequest.requestToId(parsedRequest.subscription);
|
|
72
|
+
this.queue.get(id)?.reject(new WebSocketRequestError(`Cannot complete WebSocket request: ${event.detail}`));
|
|
85
73
|
}
|
|
86
74
|
else {
|
|
87
75
|
// If the request is not recognized, use the parsed request as an id
|
|
88
|
-
const id =
|
|
89
|
-
this.
|
|
76
|
+
const id = WebSocketAsyncRequest.requestToId(parsedRequest);
|
|
77
|
+
this.queue.get(id)?.reject(new WebSocketRequestError(`Cannot complete WebSocket request: ${event.detail}`));
|
|
90
78
|
}
|
|
91
79
|
}
|
|
92
80
|
}
|
|
@@ -96,68 +84,55 @@
|
|
|
96
84
|
});
|
|
97
85
|
// Throws all pending requests if the connection is dropped
|
|
98
86
|
socket.addEventListener("close", () => {
|
|
99
|
-
this.
|
|
87
|
+
this.queue.forEach(({ reject }) => {
|
|
100
88
|
reject(new WebSocketRequestError("Cannot complete WebSocket request: connection is closed"));
|
|
101
89
|
});
|
|
102
|
-
this.
|
|
90
|
+
this.queue.clear();
|
|
103
91
|
});
|
|
104
92
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
* @param payload - The payload to send with the request.
|
|
109
|
-
* @param signal - An optional abort signal.
|
|
110
|
-
* @returns A promise that resolves with the parsed JSON response body.
|
|
111
|
-
*/
|
|
112
|
-
async request(method, payload, signal) {
|
|
93
|
+
async request(method, payload_or_signal, maybeSignal) {
|
|
94
|
+
const payload = payload_or_signal instanceof AbortSignal ? undefined : payload_or_signal;
|
|
95
|
+
const signal = payload_or_signal instanceof AbortSignal ? payload_or_signal : maybeSignal;
|
|
113
96
|
// Reject the request if the signal is aborted
|
|
114
97
|
if (signal?.aborted)
|
|
115
98
|
return Promise.reject(signal.reason);
|
|
116
|
-
// Create a request
|
|
99
|
+
// Create a request
|
|
117
100
|
let id;
|
|
118
101
|
let request;
|
|
119
102
|
if (method === "post") {
|
|
120
103
|
id = ++this.lastId;
|
|
121
104
|
request = { method, id, request: payload };
|
|
122
105
|
}
|
|
106
|
+
else if (method === "ping") {
|
|
107
|
+
id = "ping";
|
|
108
|
+
request = { method };
|
|
109
|
+
}
|
|
123
110
|
else {
|
|
124
|
-
id =
|
|
111
|
+
id = WebSocketAsyncRequest.requestToId(payload);
|
|
125
112
|
request = { method, subscription: payload };
|
|
126
113
|
}
|
|
127
114
|
// Send the request
|
|
128
115
|
this.socket.send(JSON.stringify(request));
|
|
116
|
+
this.lastRequestTime = Date.now();
|
|
129
117
|
// Wait for a response
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.pending.set(id, { resolve, reject });
|
|
137
|
-
}).finally(() => {
|
|
138
|
-
// Remove the abort listener when the promise is settled
|
|
118
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
119
|
+
this.queue.set(id, { resolve, reject });
|
|
120
|
+
const onAbort = () => reject(signal?.reason);
|
|
121
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
122
|
+
return await promise.finally(() => {
|
|
123
|
+
this.queue.delete(id);
|
|
139
124
|
signal?.removeEventListener("abort", onAbort);
|
|
140
|
-
// Clean up the pending list
|
|
141
|
-
this.pending.delete(id);
|
|
142
125
|
});
|
|
143
126
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Normalizes a request object to an ID.
|
|
146
|
-
* @param value - A request object.
|
|
147
|
-
* @returns A stringified request.
|
|
148
|
-
*/
|
|
127
|
+
/** Normalizes an object and then converts it to a string. */
|
|
149
128
|
static requestToId(value) {
|
|
150
129
|
const lowerHex = containsUppercaseHex(value) ? deepLowerHex(value) : value;
|
|
151
130
|
const sorted = deepSortKeys(lowerHex);
|
|
152
131
|
return JSON.stringify(sorted); // Also removes undefined
|
|
153
132
|
}
|
|
154
133
|
}
|
|
155
|
-
exports.
|
|
156
|
-
/**
|
|
157
|
-
* Deeply converts hexadecimal strings in an object/array to lowercase.
|
|
158
|
-
* @param obj - The object/array to convert hexadecimal strings to lowercase.
|
|
159
|
-
* @returns A new object/array with hexadecimal strings converted to lowercase.
|
|
160
|
-
*/
|
|
134
|
+
exports.WebSocketAsyncRequest = WebSocketAsyncRequest;
|
|
135
|
+
/** Deeply converts hexadecimal strings in an object/array to lowercase. */
|
|
161
136
|
function deepLowerHex(obj) {
|
|
162
137
|
if (typeof obj === "string") {
|
|
163
138
|
return /^(0X[0-9a-fA-F]*|0x[0-9a-fA-F]*[A-F][0-9a-fA-F]*)$/.test(obj) ? obj.toLowerCase() : obj;
|
|
@@ -175,20 +150,12 @@
|
|
|
175
150
|
}
|
|
176
151
|
return obj;
|
|
177
152
|
}
|
|
178
|
-
/**
|
|
179
|
-
* Check if an object contains uppercase hexadecimal strings.
|
|
180
|
-
* @param obj - The object to check.
|
|
181
|
-
* @returns True if the object contains uppercase hexadecimal strings, false otherwise.
|
|
182
|
-
*/
|
|
153
|
+
/** Check if an object contains uppercase hexadecimal strings. */
|
|
183
154
|
function containsUppercaseHex(obj) {
|
|
184
155
|
const str = JSON.stringify(obj);
|
|
185
156
|
return /0X[0-9a-fA-F]*|0x[0-9a-fA-F]*[A-F][0-9a-fA-F]*/.test(str);
|
|
186
157
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Deeply sort the keys of an object.
|
|
189
|
-
* @param obj - An object to sort the keys of.
|
|
190
|
-
* @returns A new object with sorted keys.
|
|
191
|
-
*/
|
|
158
|
+
/** Deeply sort the keys of an object. */
|
|
192
159
|
function deepSortKeys(obj) {
|
|
193
160
|
if (typeof obj !== "object" || obj === null) {
|
|
194
161
|
return obj;
|