@nktkas/hyperliquid 0.25.0-beta.3 → 0.25.0-beta.4
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 +108 -116
- package/esm/bin/_utils.d.ts +80 -0
- package/esm/bin/_utils.d.ts.map +1 -0
- package/esm/bin/_utils.js +112 -0
- package/esm/bin/_utils.js.map +1 -0
- package/esm/bin/cli.js +43 -161
- package/esm/bin/cli.js.map +1 -1
- package/esm/src/clients/exchange.d.ts +93 -93
- package/esm/src/clients/exchange.d.ts.map +1 -1
- package/esm/src/clients/exchange.js +63 -58
- package/esm/src/clients/exchange.js.map +1 -1
- package/esm/src/clients/info.d.ts +113 -113
- package/esm/src/clients/info.d.ts.map +1 -1
- package/esm/src/clients/info.js +70 -73
- package/esm/src/clients/info.js.map +1 -1
- package/esm/src/clients/multiSign.d.ts +3 -3
- package/esm/src/clients/multiSign.d.ts.map +1 -1
- package/esm/src/clients/multiSign.js +4 -2
- package/esm/src/clients/multiSign.js.map +1 -1
- package/esm/src/clients/subscription.d.ts +23 -23
- package/esm/src/clients/subscription.d.ts.map +1 -1
- package/esm/src/clients/subscription.js +8 -11
- package/esm/src/clients/subscription.js.map +1 -1
- package/esm/src/schemas/_base.d.ts +6 -8
- package/esm/src/schemas/_base.d.ts.map +1 -1
- package/esm/src/schemas/_base.js +5 -28
- package/esm/src/schemas/_base.js.map +1 -1
- package/esm/src/schemas/exchange/requests.d.ts +1676 -1657
- package/esm/src/schemas/exchange/requests.d.ts.map +1 -1
- package/esm/src/schemas/exchange/requests.js +195 -199
- package/esm/src/schemas/exchange/requests.js.map +1 -1
- package/esm/src/schemas/exchange/responses.d.ts +10 -10
- package/esm/src/schemas/exchange/responses.js +3 -3
- package/esm/src/schemas/exchange/responses.js.map +1 -1
- package/esm/src/schemas/explorer/requests.d.ts +2 -2
- package/esm/src/schemas/explorer/requests.js +3 -3
- package/esm/src/schemas/explorer/requests.js.map +1 -1
- package/esm/src/schemas/explorer/responses.d.ts +16 -16
- package/esm/src/schemas/explorer/responses.js +3 -3
- package/esm/src/schemas/explorer/responses.js.map +1 -1
- package/esm/src/schemas/info/accounts.d.ts +298 -298
- package/esm/src/schemas/info/accounts.js +24 -24
- package/esm/src/schemas/info/accounts.js.map +1 -1
- package/esm/src/schemas/info/assets.d.ts +110 -110
- package/esm/src/schemas/info/assets.js +9 -9
- package/esm/src/schemas/info/assets.js.map +1 -1
- package/esm/src/schemas/info/markets.d.ts +25 -25
- package/esm/src/schemas/info/markets.js +3 -3
- package/esm/src/schemas/info/markets.js.map +1 -1
- package/esm/src/schemas/info/orders.d.ts +104 -104
- package/esm/src/schemas/info/orders.js +3 -3
- package/esm/src/schemas/info/orders.js.map +1 -1
- package/esm/src/schemas/info/requests.d.ts +32 -32
- package/esm/src/schemas/info/requests.js +55 -55
- package/esm/src/schemas/info/requests.js.map +1 -1
- package/esm/src/schemas/info/validators.d.ts +27 -27
- package/esm/src/schemas/info/validators.js +6 -6
- package/esm/src/schemas/info/validators.js.map +1 -1
- package/esm/src/schemas/info/vaults.d.ts +46 -46
- package/esm/src/schemas/info/vaults.js +10 -10
- package/esm/src/schemas/info/vaults.js.map +1 -1
- package/esm/src/schemas/subscriptions/requests.d.ts +4 -4
- package/esm/src/schemas/subscriptions/requests.js +17 -17
- package/esm/src/schemas/subscriptions/requests.js.map +1 -1
- package/esm/src/schemas/subscriptions/responses.d.ts +401 -401
- package/esm/src/schemas/subscriptions/responses.js +14 -14
- package/esm/src/schemas/subscriptions/responses.js.map +1 -1
- package/esm/src/signing/mod.js +4 -4
- package/esm/src/signing/mod.js.map +1 -1
- package/esm/src/signing/signTypedData/private_key.js +16 -16
- package/esm/src/signing/signTypedData/private_key.js.map +1 -1
- package/esm/src/transports/_polyfills.d.ts +12 -0
- package/esm/src/transports/_polyfills.d.ts.map +1 -0
- package/esm/src/transports/_polyfills.js +40 -0
- package/esm/src/transports/_polyfills.js.map +1 -0
- package/esm/src/transports/base.d.ts +6 -6
- package/esm/src/transports/base.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.d.ts +11 -4
- package/esm/src/transports/http/http_transport.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.js +17 -6
- package/esm/src/transports/http/http_transport.js.map +1 -1
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/esm/src/transports/websocket/_hyperliquid_event_target.js +14 -33
- package/esm/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/esm/src/transports/websocket/_reconnecting_websocket.js +82 -76
- package/esm/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
- package/esm/src/transports/websocket/_websocket_async_request.d.ts +6 -0
- package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
- package/esm/src/transports/websocket/_websocket_async_request.js +49 -41
- package/esm/src/transports/websocket/_websocket_async_request.js.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.d.ts +48 -70
- package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.js +90 -103
- package/esm/src/transports/websocket/websocket_transport.js.map +1 -1
- package/package.json +3 -7
- package/script/bin/_utils.d.ts +80 -0
- package/script/bin/_utils.d.ts.map +1 -0
- package/script/bin/_utils.js +116 -0
- package/script/bin/_utils.js.map +1 -0
- package/script/bin/cli.js +43 -164
- package/script/bin/cli.js.map +1 -1
- package/script/src/clients/exchange.d.ts +93 -93
- package/script/src/clients/exchange.d.ts.map +1 -1
- package/script/src/clients/exchange.js +62 -57
- package/script/src/clients/exchange.js.map +1 -1
- package/script/src/clients/info.d.ts +113 -113
- package/script/src/clients/info.d.ts.map +1 -1
- package/script/src/clients/info.js +70 -73
- package/script/src/clients/info.js.map +1 -1
- package/script/src/clients/multiSign.d.ts +3 -3
- package/script/src/clients/multiSign.d.ts.map +1 -1
- package/script/src/clients/multiSign.js +10 -8
- package/script/src/clients/multiSign.js.map +1 -1
- package/script/src/clients/subscription.d.ts +23 -23
- package/script/src/clients/subscription.d.ts.map +1 -1
- package/script/src/clients/subscription.js +8 -11
- package/script/src/clients/subscription.js.map +1 -1
- package/script/src/schemas/_base.d.ts +6 -8
- package/script/src/schemas/_base.d.ts.map +1 -1
- package/script/src/schemas/_base.js +6 -29
- package/script/src/schemas/_base.js.map +1 -1
- package/script/src/schemas/exchange/requests.d.ts +1676 -1657
- package/script/src/schemas/exchange/requests.d.ts.map +1 -1
- package/script/src/schemas/exchange/requests.js +194 -198
- package/script/src/schemas/exchange/requests.js.map +1 -1
- package/script/src/schemas/exchange/responses.d.ts +10 -10
- package/script/src/schemas/exchange/responses.js +2 -2
- package/script/src/schemas/exchange/responses.js.map +1 -1
- package/script/src/schemas/explorer/requests.d.ts +2 -2
- package/script/src/schemas/explorer/requests.js +2 -2
- package/script/src/schemas/explorer/requests.js.map +1 -1
- package/script/src/schemas/explorer/responses.d.ts +16 -16
- package/script/src/schemas/explorer/responses.js +2 -2
- package/script/src/schemas/explorer/responses.js.map +1 -1
- package/script/src/schemas/info/accounts.d.ts +298 -298
- package/script/src/schemas/info/accounts.js +23 -23
- package/script/src/schemas/info/accounts.js.map +1 -1
- package/script/src/schemas/info/assets.d.ts +110 -110
- package/script/src/schemas/info/assets.js +8 -8
- package/script/src/schemas/info/assets.js.map +1 -1
- package/script/src/schemas/info/markets.d.ts +25 -25
- package/script/src/schemas/info/markets.js +2 -2
- package/script/src/schemas/info/markets.js.map +1 -1
- package/script/src/schemas/info/orders.d.ts +104 -104
- package/script/src/schemas/info/orders.js +2 -2
- package/script/src/schemas/info/orders.js.map +1 -1
- package/script/src/schemas/info/requests.d.ts +32 -32
- package/script/src/schemas/info/requests.js +54 -54
- package/script/src/schemas/info/requests.js.map +1 -1
- package/script/src/schemas/info/validators.d.ts +27 -27
- package/script/src/schemas/info/validators.js +5 -5
- package/script/src/schemas/info/validators.js.map +1 -1
- package/script/src/schemas/info/vaults.d.ts +46 -46
- package/script/src/schemas/info/vaults.js +9 -9
- package/script/src/schemas/info/vaults.js.map +1 -1
- package/script/src/schemas/subscriptions/requests.d.ts +4 -4
- package/script/src/schemas/subscriptions/requests.js +16 -16
- package/script/src/schemas/subscriptions/requests.js.map +1 -1
- package/script/src/schemas/subscriptions/responses.d.ts +401 -401
- package/script/src/schemas/subscriptions/responses.js +13 -13
- package/script/src/schemas/subscriptions/responses.js.map +1 -1
- package/script/src/signing/mod.js +37 -4
- package/script/src/signing/mod.js.map +1 -1
- package/script/src/signing/signTypedData/private_key.js +49 -16
- package/script/src/signing/signTypedData/private_key.js.map +1 -1
- package/script/src/transports/_polyfills.d.ts +12 -0
- package/script/src/transports/_polyfills.d.ts.map +1 -0
- package/script/src/transports/_polyfills.js +43 -0
- package/script/src/transports/_polyfills.js.map +1 -0
- package/script/src/transports/base.d.ts +6 -6
- package/script/src/transports/base.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.d.ts +11 -4
- package/script/src/transports/http/http_transport.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.js +17 -6
- package/script/src/transports/http/http_transport.js.map +1 -1
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/script/src/transports/websocket/_hyperliquid_event_target.js +47 -33
- package/script/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
- package/script/src/transports/websocket/_reconnecting_websocket.js +82 -76
- package/script/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
- package/script/src/transports/websocket/_websocket_async_request.d.ts +6 -0
- package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
- package/script/src/transports/websocket/_websocket_async_request.js +52 -43
- package/script/src/transports/websocket/_websocket_async_request.js.map +1 -1
- package/script/src/transports/websocket/websocket_transport.d.ts +48 -70
- package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/script/src/transports/websocket/websocket_transport.js +92 -105
- package/script/src/transports/websocket/websocket_transport.js.map +1 -1
- package/src/bin/_utils.ts +185 -0
- package/src/bin/cli.ts +49 -171
- package/src/src/clients/exchange.ts +160 -149
- package/src/src/clients/info.ts +128 -128
- package/src/src/clients/multiSign.ts +15 -13
- package/src/src/clients/subscription.ts +32 -32
- package/src/src/schemas/_base.ts +18 -40
- package/src/src/schemas/exchange/requests.ts +202 -199
- package/src/src/schemas/exchange/responses.ts +3 -3
- package/src/src/schemas/explorer/requests.ts +3 -3
- package/src/src/schemas/explorer/responses.ts +3 -3
- package/src/src/schemas/info/accounts.ts +24 -24
- package/src/src/schemas/info/assets.ts +9 -9
- package/src/src/schemas/info/markets.ts +3 -3
- package/src/src/schemas/info/orders.ts +3 -3
- package/src/src/schemas/info/requests.ts +55 -55
- package/src/src/schemas/info/validators.ts +6 -6
- package/src/src/schemas/info/vaults.ts +10 -10
- package/src/src/schemas/subscriptions/requests.ts +17 -17
- package/src/src/schemas/subscriptions/responses.ts +14 -14
- package/src/src/signing/mod.ts +4 -4
- package/src/src/signing/signTypedData/private_key.ts +17 -17
- package/src/src/transports/_polyfills.ts +41 -0
- package/src/src/transports/base.ts +6 -6
- package/src/src/transports/http/http_transport.ts +25 -14
- package/src/src/transports/websocket/_hyperliquid_event_target.ts +24 -51
- package/src/src/transports/websocket/_reconnecting_websocket.ts +107 -119
- package/src/src/transports/websocket/_websocket_async_request.ts +57 -59
- package/src/src/transports/websocket/websocket_transport.ts +126 -167
|
@@ -1,28 +1,35 @@
|
|
|
1
|
+
import { TransportError } from "../base.js";
|
|
2
|
+
import { Promise_ } from "../_polyfills.js";
|
|
1
3
|
import type { ReconnectingWebSocket } from "./_reconnecting_websocket.js";
|
|
2
|
-
import type {
|
|
3
|
-
import { WebSocketRequestError } from "./websocket_transport.js";
|
|
4
|
+
import type { HyperliquidEventTarget } from "./_hyperliquid_event_target.js";
|
|
4
5
|
|
|
5
6
|
interface PostRequest {
|
|
6
7
|
method: "post";
|
|
7
8
|
id: number;
|
|
8
9
|
request: unknown;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
11
|
interface SubscribeUnsubscribeRequest {
|
|
12
12
|
method: "subscribe" | "unsubscribe";
|
|
13
13
|
subscription: unknown;
|
|
14
14
|
}
|
|
15
|
-
|
|
16
15
|
interface PingRequest {
|
|
17
16
|
method: "ping";
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
/** Error thrown when a WebSocket request fails. */
|
|
20
|
+
export class WebSocketRequestError extends TransportError {
|
|
21
|
+
constructor(message?: string, options?: ErrorOptions) {
|
|
22
|
+
super(message, options);
|
|
23
|
+
this.name = "WebSocketRequestError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
/**
|
|
21
28
|
* Manages WebSocket requests to the Hyperliquid API.
|
|
22
29
|
* Handles request creation, sending, and mapping responses to their corresponding requests.
|
|
23
30
|
*/
|
|
24
31
|
export class WebSocketAsyncRequest {
|
|
25
|
-
protected lastId
|
|
32
|
+
protected lastId = 0;
|
|
26
33
|
protected queue: {
|
|
27
34
|
id: number | string;
|
|
28
35
|
// deno-lint-ignore no-explicit-any
|
|
@@ -30,7 +37,8 @@ export class WebSocketAsyncRequest {
|
|
|
30
37
|
// deno-lint-ignore no-explicit-any
|
|
31
38
|
reject: (reason?: any) => void;
|
|
32
39
|
}[] = [];
|
|
33
|
-
|
|
40
|
+
/** Timestamp of the last request sent. */
|
|
41
|
+
lastRequestTime = 0;
|
|
34
42
|
|
|
35
43
|
/**
|
|
36
44
|
* Creates a new WebSocket async request handler.
|
|
@@ -40,35 +48,30 @@ export class WebSocketAsyncRequest {
|
|
|
40
48
|
constructor(protected socket: ReconnectingWebSocket, hlEvents: HyperliquidEventTarget) {
|
|
41
49
|
// Monitor responses and match the pending request
|
|
42
50
|
hlEvents.addEventListener("subscriptionResponse", (event) => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
// Use a stringified request as an id
|
|
46
|
-
const id = WebSocketAsyncRequest.requestToId(detail);
|
|
47
|
-
this.queue.findLast((item) => item.id === id)?.resolve(detail);
|
|
51
|
+
const id = WebSocketAsyncRequest.requestToId(event.detail);
|
|
52
|
+
this.queue.find((x) => x.id === id)?.resolve(event.detail);
|
|
48
53
|
});
|
|
49
54
|
hlEvents.addEventListener("post", (event) => {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this.queue.
|
|
55
|
+
const data = event.detail.response.type === "info"
|
|
56
|
+
? event.detail.response.payload.data
|
|
57
|
+
: event.detail.response.payload;
|
|
58
|
+
this.queue.find((x) => x.id === event.detail.id)?.resolve(data);
|
|
54
59
|
});
|
|
55
60
|
hlEvents.addEventListener("pong", () => {
|
|
56
|
-
this.queue.
|
|
61
|
+
this.queue.find((x) => x.id === "ping")?.resolve();
|
|
57
62
|
});
|
|
58
63
|
hlEvents.addEventListener("error", (event) => {
|
|
59
|
-
const detail = (event as HyperliquidEventMap["error"]).detail;
|
|
60
|
-
|
|
61
64
|
try {
|
|
62
65
|
// Error event doesn't have an id, use original request to match
|
|
63
|
-
const request = detail.match(/{.*}/)?.[0];
|
|
66
|
+
const request = event.detail.match(/{.*}/)?.[0];
|
|
64
67
|
if (!request) return;
|
|
65
68
|
|
|
66
|
-
const parsedRequest = JSON.parse(request)
|
|
69
|
+
const parsedRequest = JSON.parse(request);
|
|
67
70
|
|
|
68
71
|
// For `post` requests
|
|
69
72
|
if ("id" in parsedRequest && typeof parsedRequest.id === "number") {
|
|
70
|
-
this.queue.
|
|
71
|
-
?.reject(new WebSocketRequestError(
|
|
73
|
+
this.queue.find((x) => x.id === parsedRequest.id)
|
|
74
|
+
?.reject(new WebSocketRequestError(event.detail));
|
|
72
75
|
return;
|
|
73
76
|
}
|
|
74
77
|
|
|
@@ -78,48 +81,54 @@ export class WebSocketAsyncRequest {
|
|
|
78
81
|
typeof parsedRequest.subscription === "object" && parsedRequest.subscription !== null
|
|
79
82
|
) {
|
|
80
83
|
const id = WebSocketAsyncRequest.requestToId(parsedRequest);
|
|
81
|
-
this.queue.
|
|
82
|
-
?.reject(new WebSocketRequestError(
|
|
84
|
+
this.queue.find((x) => x.id === id)
|
|
85
|
+
?.reject(new WebSocketRequestError(event.detail));
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
// For `Already subscribed` and `Invalid subscription` requests
|
|
87
|
-
if (
|
|
90
|
+
if (
|
|
91
|
+
event.detail.startsWith("Already subscribed") ||
|
|
92
|
+
event.detail.startsWith("Invalid subscription")
|
|
93
|
+
) {
|
|
88
94
|
const id = WebSocketAsyncRequest.requestToId({
|
|
89
95
|
method: "subscribe",
|
|
90
96
|
subscription: parsedRequest,
|
|
91
97
|
});
|
|
92
|
-
this.queue.
|
|
93
|
-
?.reject(new WebSocketRequestError(
|
|
98
|
+
this.queue.find((x) => x.id === id)
|
|
99
|
+
?.reject(new WebSocketRequestError(event.detail));
|
|
94
100
|
return;
|
|
95
101
|
}
|
|
102
|
+
|
|
96
103
|
// For `Already unsubscribed` requests
|
|
97
|
-
if (detail.startsWith("Already unsubscribed")) {
|
|
104
|
+
if (event.detail.startsWith("Already unsubscribed")) {
|
|
98
105
|
const id = WebSocketAsyncRequest.requestToId({
|
|
99
106
|
method: "unsubscribe",
|
|
100
107
|
subscription: parsedRequest,
|
|
101
108
|
});
|
|
102
|
-
this.queue.
|
|
103
|
-
?.reject(new WebSocketRequestError(
|
|
109
|
+
this.queue.find((x) => x.id === id)
|
|
110
|
+
?.reject(new WebSocketRequestError(event.detail));
|
|
104
111
|
return;
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
// For unknown requests
|
|
108
115
|
const id = WebSocketAsyncRequest.requestToId(parsedRequest);
|
|
109
|
-
this.queue.
|
|
110
|
-
?.reject(new WebSocketRequestError(
|
|
116
|
+
this.queue.find((x) => x.id === id)
|
|
117
|
+
?.reject(new WebSocketRequestError(event.detail));
|
|
111
118
|
} catch {
|
|
112
119
|
// Ignore JSON parsing errors
|
|
113
120
|
}
|
|
114
121
|
});
|
|
115
122
|
|
|
116
123
|
// Throws all pending requests if the connection is dropped
|
|
117
|
-
|
|
124
|
+
const handleClose = () => {
|
|
118
125
|
this.queue.forEach(({ reject }) => {
|
|
119
126
|
reject(new WebSocketRequestError("WebSocket connection closed."));
|
|
120
127
|
});
|
|
121
128
|
this.queue = [];
|
|
122
|
-
}
|
|
129
|
+
};
|
|
130
|
+
socket.addEventListener("close", handleClose);
|
|
131
|
+
socket.addEventListener("error", handleClose);
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
/**
|
|
@@ -130,17 +139,17 @@ export class WebSocketAsyncRequest {
|
|
|
130
139
|
async request<T>(method: "post" | "subscribe" | "unsubscribe", payload: unknown, signal?: AbortSignal): Promise<T>;
|
|
131
140
|
async request<T>(
|
|
132
141
|
method: "post" | "subscribe" | "unsubscribe" | "ping",
|
|
133
|
-
|
|
142
|
+
payloadOrSignal?: unknown | AbortSignal,
|
|
134
143
|
maybeSignal?: AbortSignal,
|
|
135
144
|
): Promise<T> {
|
|
136
|
-
const payload =
|
|
137
|
-
const signal =
|
|
145
|
+
const payload = payloadOrSignal instanceof AbortSignal ? undefined : payloadOrSignal;
|
|
146
|
+
const signal = payloadOrSignal instanceof AbortSignal ? payloadOrSignal : maybeSignal;
|
|
138
147
|
|
|
139
148
|
// Reject the request if the signal is aborted
|
|
140
149
|
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
141
150
|
// or if the WebSocket connection is permanently closed
|
|
142
|
-
if (this.socket.
|
|
143
|
-
return Promise.reject(this.socket.
|
|
151
|
+
if (this.socket.terminateSignal.aborted) {
|
|
152
|
+
return Promise.reject(this.socket.terminateSignal.reason);
|
|
144
153
|
}
|
|
145
154
|
|
|
146
155
|
// Create a request
|
|
@@ -162,14 +171,14 @@ export class WebSocketAsyncRequest {
|
|
|
162
171
|
this.lastRequestTime = Date.now();
|
|
163
172
|
|
|
164
173
|
// Wait for a response
|
|
165
|
-
const { promise, resolve, reject } =
|
|
174
|
+
const { promise, resolve, reject } = Promise_.withResolvers<T>();
|
|
166
175
|
this.queue.push({ id, resolve, reject });
|
|
167
176
|
|
|
168
177
|
const onAbort = () => reject(signal?.reason);
|
|
169
178
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
170
179
|
|
|
171
180
|
return await promise.finally(() => {
|
|
172
|
-
const index = this.queue.
|
|
181
|
+
const index = this.queue.findIndex((item) => item.id === id);
|
|
173
182
|
if (index !== -1) this.queue.splice(index, 1);
|
|
174
183
|
|
|
175
184
|
signal?.removeEventListener("abort", onAbort);
|
|
@@ -179,51 +188,40 @@ export class WebSocketAsyncRequest {
|
|
|
179
188
|
/** Normalizes an object and then converts it to a string. */
|
|
180
189
|
static requestToId(value: unknown): string {
|
|
181
190
|
const lowerHex = deepLowerHex(value);
|
|
182
|
-
const
|
|
183
|
-
return JSON.stringify(
|
|
191
|
+
const sortedKeys = deepSortKeys(lowerHex);
|
|
192
|
+
return JSON.stringify(sortedKeys); // also removes undefined
|
|
184
193
|
}
|
|
185
194
|
}
|
|
186
195
|
|
|
187
|
-
/** Deeply converts hexadecimal strings in an object/array
|
|
196
|
+
/** Deeply converts hexadecimal strings to lowercase in an object/array. */
|
|
188
197
|
function deepLowerHex(obj: unknown): unknown {
|
|
189
198
|
if (typeof obj === "string") {
|
|
190
|
-
return /^
|
|
199
|
+
return /^0[xX][0-9a-fA-F]+$/.test(obj) ? obj.toLowerCase() : obj;
|
|
191
200
|
}
|
|
192
|
-
|
|
193
201
|
if (Array.isArray(obj)) {
|
|
194
202
|
return obj.map((value) => deepLowerHex(value));
|
|
195
203
|
}
|
|
196
|
-
|
|
197
204
|
if (typeof obj === "object" && obj !== null) {
|
|
198
205
|
const result: Record<string, unknown> = {};
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
for (const [key, value] of entries) {
|
|
206
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
202
207
|
result[key] = deepLowerHex(value);
|
|
203
208
|
}
|
|
204
|
-
|
|
205
209
|
return result;
|
|
206
210
|
}
|
|
207
|
-
|
|
208
211
|
return obj;
|
|
209
212
|
}
|
|
210
213
|
|
|
211
|
-
/** Deeply sort
|
|
214
|
+
/** Deeply sort keys of an object alphabetically. */
|
|
212
215
|
function deepSortKeys<T>(obj: T): T {
|
|
213
216
|
if (typeof obj !== "object" || obj === null) {
|
|
214
217
|
return obj;
|
|
215
218
|
}
|
|
216
|
-
|
|
217
219
|
if (Array.isArray(obj)) {
|
|
218
220
|
return obj.map(deepSortKeys) as T;
|
|
219
221
|
}
|
|
220
|
-
|
|
221
222
|
const result: Record<string, unknown> = {};
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
for (const key of keys) {
|
|
223
|
+
for (const key of Object.keys(obj).sort()) {
|
|
225
224
|
result[key] = deepSortKeys((obj as Record<string, unknown>)[key]);
|
|
226
225
|
}
|
|
227
|
-
|
|
228
226
|
return result as T;
|
|
229
227
|
}
|