@nktkas/hyperliquid 0.25.0-beta.2 → 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 +114 -106
- 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.d.ts +3 -0
- package/esm/bin/cli.d.ts.map +1 -0
- package/esm/bin/cli.js +334 -0
- package/esm/bin/cli.js.map +1 -0
- package/esm/src/{errors.d.ts → _errors.d.ts} +1 -1
- package/esm/src/_errors.d.ts.map +1 -0
- package/esm/src/{errors.js → _errors.js} +1 -1
- package/esm/src/_errors.js.map +1 -0
- package/esm/src/clients/exchange.d.ts +91 -91
- package/esm/src/clients/exchange.d.ts.map +1 -1
- package/esm/src/clients/exchange.js +61 -56
- package/esm/src/clients/exchange.js.map +1 -1
- package/esm/src/clients/info.d.ts +134 -112
- package/esm/src/clients/info.d.ts.map +1 -1
- package/esm/src/clients/info.js +95 -72
- package/esm/src/clients/info.js.map +1 -1
- package/esm/src/clients/multiSign.d.ts +2 -2
- package/esm/src/clients/multiSign.d.ts.map +1 -1
- package/esm/src/clients/multiSign.js +3 -1
- 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/mod.d.ts +21 -0
- package/esm/src/mod.d.ts.map +1 -0
- package/esm/src/mod.js +14 -0
- package/esm/src/mod.js.map +1 -0
- package/esm/src/schemas/_base.d.ts +8 -6
- package/esm/src/schemas/_base.d.ts.map +1 -1
- package/esm/src/schemas/_base.js +6 -4
- package/esm/src/schemas/_base.js.map +1 -1
- package/esm/src/schemas/exchange/requests.d.ts +332 -313
- package/esm/src/schemas/exchange/requests.d.ts.map +1 -1
- package/esm/src/schemas/exchange/requests.js +52 -61
- 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 +1 -1
- package/esm/src/schemas/explorer/requests.js +2 -2
- 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 +975 -229
- package/esm/src/schemas/info/accounts.d.ts.map +1 -1
- package/esm/src/schemas/info/accounts.js +65 -21
- 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 +175 -175
- 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 +31 -16
- package/esm/src/schemas/info/requests.d.ts.map +1 -1
- package/esm/src/schemas/info/requests.js +51 -40
- package/esm/src/schemas/info/requests.js.map +1 -1
- package/esm/src/schemas/info/validators.d.ts +30 -30
- package/esm/src/schemas/info/validators.d.ts.map +1 -1
- package/esm/src/schemas/info/validators.js +8 -8
- 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/mod.d.ts +3 -3
- package/esm/src/schemas/mod.d.ts.map +1 -1
- package/esm/src/schemas/mod.js +3 -3
- package/esm/src/schemas/mod.js.map +1 -1
- package/esm/src/schemas/subscriptions/requests.d.ts +4 -4
- package/esm/src/schemas/subscriptions/requests.d.ts.map +1 -1
- 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 +618 -618
- package/esm/src/schemas/subscriptions/responses.js +14 -14
- package/esm/src/schemas/subscriptions/responses.js.map +1 -1
- package/esm/src/signing/mod.d.ts +1 -1
- package/esm/src/signing/mod.d.ts.map +1 -1
- package/esm/src/signing/mod.js +6 -6
- package/esm/src/signing/mod.js.map +1 -1
- package/esm/src/signing/signTypedData/ethers.d.ts.map +1 -0
- package/esm/src/signing/signTypedData/ethers.js.map +1 -0
- package/esm/src/signing/signTypedData/mod.d.ts.map +1 -0
- package/esm/src/signing/signTypedData/mod.js.map +1 -0
- package/esm/src/signing/signTypedData/private_key.d.ts.map +1 -0
- package/esm/src/signing/{_signTypedData → signTypedData}/private_key.js +18 -17
- package/esm/src/signing/signTypedData/private_key.js.map +1 -0
- package/esm/src/signing/signTypedData/viem.d.ts.map +1 -0
- package/esm/src/signing/signTypedData/viem.js.map +1 -0
- 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 +8 -8
- package/esm/src/transports/base.d.ts.map +1 -1
- package/esm/src/transports/base.js +2 -2
- package/esm/src/transports/base.js.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 +12 -8
- 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.d.ts +3 -0
- package/script/bin/cli.d.ts.map +1 -0
- package/script/bin/cli.js +369 -0
- package/script/bin/cli.js.map +1 -0
- package/script/src/{errors.d.ts → _errors.d.ts} +1 -1
- package/script/src/_errors.d.ts.map +1 -0
- package/script/src/{errors.js → _errors.js} +1 -1
- package/script/src/_errors.js.map +1 -0
- package/script/src/clients/exchange.d.ts +91 -91
- package/script/src/clients/exchange.d.ts.map +1 -1
- package/script/src/clients/exchange.js +61 -56
- package/script/src/clients/exchange.js.map +1 -1
- package/script/src/clients/info.d.ts +134 -112
- package/script/src/clients/info.d.ts.map +1 -1
- package/script/src/clients/info.js +94 -71
- package/script/src/clients/info.js.map +1 -1
- package/script/src/clients/multiSign.d.ts +2 -2
- package/script/src/clients/multiSign.d.ts.map +1 -1
- package/script/src/clients/multiSign.js +9 -7
- 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/mod.d.ts +21 -0
- package/script/src/mod.d.ts.map +1 -0
- package/script/{mod.js → src/mod.js} +12 -8
- package/script/src/mod.js.map +1 -0
- package/script/src/schemas/_base.d.ts +8 -6
- package/script/src/schemas/_base.d.ts.map +1 -1
- package/script/src/schemas/_base.js +7 -5
- package/script/src/schemas/_base.js.map +1 -1
- package/script/src/schemas/exchange/requests.d.ts +332 -313
- package/script/src/schemas/exchange/requests.d.ts.map +1 -1
- package/script/src/schemas/exchange/requests.js +51 -60
- 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 +1 -1
- package/script/src/schemas/explorer/requests.js +1 -1
- 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 +975 -229
- package/script/src/schemas/info/accounts.d.ts.map +1 -1
- package/script/src/schemas/info/accounts.js +65 -21
- 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 +175 -175
- 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 +31 -16
- package/script/src/schemas/info/requests.d.ts.map +1 -1
- package/script/src/schemas/info/requests.js +51 -40
- package/script/src/schemas/info/requests.js.map +1 -1
- package/script/src/schemas/info/validators.d.ts +30 -30
- package/script/src/schemas/info/validators.d.ts.map +1 -1
- package/script/src/schemas/info/validators.js +7 -7
- 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/mod.d.ts +3 -3
- package/script/src/schemas/mod.d.ts.map +1 -1
- package/script/src/schemas/mod.js +4 -4
- package/script/src/schemas/mod.js.map +1 -1
- package/script/src/schemas/subscriptions/requests.d.ts +4 -4
- package/script/src/schemas/subscriptions/requests.d.ts.map +1 -1
- 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 +618 -618
- package/script/src/schemas/subscriptions/responses.js +13 -13
- package/script/src/schemas/subscriptions/responses.js.map +1 -1
- package/script/src/signing/mod.d.ts +1 -1
- package/script/src/signing/mod.d.ts.map +1 -1
- package/script/src/signing/mod.js +40 -7
- package/script/src/signing/mod.js.map +1 -1
- package/script/src/signing/signTypedData/ethers.d.ts.map +1 -0
- package/script/src/signing/signTypedData/ethers.js.map +1 -0
- package/script/src/signing/signTypedData/mod.d.ts.map +1 -0
- package/script/src/signing/signTypedData/mod.js.map +1 -0
- package/script/src/signing/signTypedData/private_key.d.ts.map +1 -0
- package/script/src/signing/{_signTypedData → signTypedData}/private_key.js +55 -21
- package/script/src/signing/signTypedData/private_key.js.map +1 -0
- package/script/src/signing/signTypedData/viem.d.ts.map +1 -0
- package/script/src/signing/signTypedData/viem.js.map +1 -0
- 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 +8 -8
- package/script/src/transports/base.d.ts.map +1 -1
- package/script/src/transports/base.js +3 -3
- package/script/src/transports/base.js.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 +359 -0
- package/src/src/clients/exchange.ts +155 -144
- package/src/src/clients/info.ts +158 -124
- package/src/src/clients/multiSign.ts +13 -11
- package/src/src/clients/subscription.ts +32 -32
- package/src/src/mod.ts +29 -0
- package/src/src/schemas/_base.ts +25 -8
- package/src/src/schemas/exchange/requests.ts +59 -61
- package/src/src/schemas/exchange/responses.ts +3 -3
- package/src/src/schemas/explorer/requests.ts +2 -2
- package/src/src/schemas/explorer/responses.ts +3 -3
- package/src/src/schemas/info/accounts.ts +129 -21
- 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 +72 -40
- package/src/src/schemas/info/validators.ts +22 -24
- package/src/src/schemas/info/vaults.ts +10 -10
- package/src/src/schemas/mod.ts +3 -3
- package/src/src/schemas/subscriptions/requests.ts +27 -17
- package/src/src/schemas/subscriptions/responses.ts +14 -14
- package/src/src/signing/mod.ts +6 -6
- package/src/src/signing/{_signTypedData → signTypedData}/private_key.ts +22 -17
- package/src/src/transports/_polyfills.ts +41 -0
- package/src/src/transports/base.ts +8 -8
- 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
- package/esm/mod.d.ts +0 -20
- package/esm/mod.d.ts.map +0 -1
- package/esm/mod.js +0 -12
- package/esm/mod.js.map +0 -1
- package/esm/src/errors.d.ts.map +0 -1
- package/esm/src/errors.js.map +0 -1
- package/esm/src/signing/_signTypedData/ethers.d.ts.map +0 -1
- package/esm/src/signing/_signTypedData/ethers.js.map +0 -1
- package/esm/src/signing/_signTypedData/mod.d.ts.map +0 -1
- package/esm/src/signing/_signTypedData/mod.js.map +0 -1
- package/esm/src/signing/_signTypedData/private_key.d.ts.map +0 -1
- package/esm/src/signing/_signTypedData/private_key.js.map +0 -1
- package/esm/src/signing/_signTypedData/viem.d.ts.map +0 -1
- package/esm/src/signing/_signTypedData/viem.js.map +0 -1
- package/script/mod.d.ts +0 -20
- package/script/mod.d.ts.map +0 -1
- package/script/mod.js.map +0 -1
- package/script/src/errors.d.ts.map +0 -1
- package/script/src/errors.js.map +0 -1
- package/script/src/signing/_signTypedData/ethers.d.ts.map +0 -1
- package/script/src/signing/_signTypedData/ethers.js.map +0 -1
- package/script/src/signing/_signTypedData/mod.d.ts.map +0 -1
- package/script/src/signing/_signTypedData/mod.js.map +0 -1
- package/script/src/signing/_signTypedData/private_key.d.ts.map +0 -1
- package/script/src/signing/_signTypedData/private_key.js.map +0 -1
- package/script/src/signing/_signTypedData/viem.d.ts.map +0 -1
- package/script/src/signing/_signTypedData/viem.js.map +0 -1
- package/src/mod.ts +0 -28
- /package/esm/src/signing/{_signTypedData → signTypedData}/ethers.d.ts +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/ethers.js +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/mod.d.ts +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/mod.js +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/private_key.d.ts +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/viem.d.ts +0 -0
- /package/esm/src/signing/{_signTypedData → signTypedData}/viem.js +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/ethers.d.ts +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/ethers.js +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/mod.d.ts +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/mod.js +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/private_key.d.ts +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/viem.d.ts +0 -0
- /package/script/src/signing/{_signTypedData → signTypedData}/viem.js +0 -0
- /package/src/src/{errors.ts → _errors.ts} +0 -0
- /package/src/src/signing/{_signTypedData → signTypedData}/ethers.ts +0 -0
- /package/src/src/signing/{_signTypedData → signTypedData}/mod.ts +0 -0
- /package/src/src/signing/{_signTypedData → signTypedData}/viem.ts +0 -0
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/** Event channel name. */
|
|
6
|
-
channel: string;
|
|
7
|
-
/** Channel-specific data. */
|
|
8
|
-
data: unknown;
|
|
9
|
-
}
|
|
1
|
+
import { TypedEventTarget } from "typescript-event-target";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { CustomEvent_ } from "../_polyfills.js";
|
|
4
|
+
import { BlockDetails, TxDetails } from "../../schemas/mod.js";
|
|
10
5
|
|
|
11
6
|
/** Response to subscribe to or unsubscribe from an event. */
|
|
12
|
-
interface
|
|
13
|
-
/** Type of
|
|
7
|
+
interface SubscribeUnsubscribeResponse {
|
|
8
|
+
/** Type of response */
|
|
14
9
|
method: "subscribe" | "unsubscribe";
|
|
15
|
-
/** Original
|
|
10
|
+
/** Original request. */
|
|
16
11
|
subscription: unknown;
|
|
17
12
|
}
|
|
18
13
|
|
|
@@ -56,8 +51,8 @@ interface PostResponse {
|
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
/** Base system events and dynamic channel events for Hyperliquid WebSocket API. */
|
|
59
|
-
|
|
60
|
-
subscriptionResponse: CustomEvent<
|
|
54
|
+
interface HyperliquidEventMap {
|
|
55
|
+
subscriptionResponse: CustomEvent<SubscribeUnsubscribeResponse>;
|
|
61
56
|
post: CustomEvent<PostResponse>;
|
|
62
57
|
error: CustomEvent<string>;
|
|
63
58
|
pong: CustomEvent<undefined>;
|
|
@@ -67,19 +62,26 @@ export interface HyperliquidEventMap {
|
|
|
67
62
|
[key: string]: CustomEvent<any>;
|
|
68
63
|
}
|
|
69
64
|
|
|
65
|
+
const HyperliquidEventSchema = v.object({ channel: v.string(), data: v.unknown() });
|
|
66
|
+
const ExplorerBlockEventSchema = v.pipe(
|
|
67
|
+
v.array(v.omit(v.object({ ...BlockDetails.entries }), ["txs"])),
|
|
68
|
+
v.minLength(1),
|
|
69
|
+
);
|
|
70
|
+
const ExplorerTxsEventSchema = v.pipe(v.array(TxDetails), v.minLength(1));
|
|
71
|
+
|
|
70
72
|
/** Listens for WebSocket messages and sends them as Hyperliquid typed events. */
|
|
71
|
-
export class HyperliquidEventTarget extends
|
|
73
|
+
export class HyperliquidEventTarget extends TypedEventTarget<HyperliquidEventMap> {
|
|
72
74
|
constructor(socket: WebSocket) {
|
|
73
75
|
super();
|
|
74
76
|
socket.addEventListener("message", (event) => {
|
|
75
77
|
try {
|
|
76
|
-
const msg = JSON.parse(event.data)
|
|
77
|
-
if (
|
|
78
|
-
this.dispatchEvent(new
|
|
79
|
-
} else if (
|
|
80
|
-
this.dispatchEvent(new
|
|
81
|
-
} else if (
|
|
82
|
-
this.dispatchEvent(new
|
|
78
|
+
const msg = JSON.parse(event.data);
|
|
79
|
+
if (v.is(HyperliquidEventSchema, msg)) {
|
|
80
|
+
this.dispatchEvent(new CustomEvent_(msg.channel, { detail: msg.data }));
|
|
81
|
+
} else if (v.is(ExplorerBlockEventSchema, msg)) {
|
|
82
|
+
this.dispatchEvent(new CustomEvent_("_explorerBlock", { detail: msg }));
|
|
83
|
+
} else if (v.is(ExplorerTxsEventSchema, msg)) {
|
|
84
|
+
this.dispatchEvent(new CustomEvent_("_explorerTxs", { detail: msg }));
|
|
83
85
|
}
|
|
84
86
|
} catch {
|
|
85
87
|
// Ignore JSON parsing errors
|
|
@@ -87,32 +89,3 @@ export class HyperliquidEventTarget extends EventTarget {
|
|
|
87
89
|
});
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
|
-
|
|
91
|
-
/** Type guard for Hyperliquid messages. */
|
|
92
|
-
function isHyperliquidMsg(value: unknown): value is HyperliquidMsg {
|
|
93
|
-
return typeof value === "object" && value !== null &&
|
|
94
|
-
"channel" in value && typeof value.channel === "string";
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** Type guard for explorer block messages. */
|
|
98
|
-
function isExplorerBlockMsg(value: unknown): value is Omit<BlockDetails, "txs">[] {
|
|
99
|
-
return Array.isArray(value) && value.length > 0 &&
|
|
100
|
-
(typeof value[0] === "object" && value[0] !== null && !Array.isArray(value[0]) &&
|
|
101
|
-
"height" in value[0] && typeof value[0].height === "number" &&
|
|
102
|
-
"blockTime" in value[0] && typeof value[0].blockTime === "number" &&
|
|
103
|
-
"hash" in value[0] && typeof value[0].hash === "string" &&
|
|
104
|
-
"proposer" in value[0] && typeof value[0].proposer === "string" &&
|
|
105
|
-
"numTxs" in value[0] && typeof value[0].numTxs === "number");
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Type guard for explorer transactions messages. */
|
|
109
|
-
function isExplorerTxsMsg(value: unknown): value is TxDetails[] {
|
|
110
|
-
return Array.isArray(value) && value.length > 0 &&
|
|
111
|
-
(typeof value[0] === "object" && value[0] !== null && !Array.isArray(value[0]) &&
|
|
112
|
-
"action" in value[0] && typeof value[0].action === "object" && value[0].action !== null &&
|
|
113
|
-
"block" in value[0] && typeof value[0].block === "number" &&
|
|
114
|
-
"error" in value[0] && (typeof value[0].error === "string" || value[0].error === null) &&
|
|
115
|
-
"hash" in value[0] && typeof value[0].hash === "string" &&
|
|
116
|
-
"time" in value[0] && typeof value[0].time === "number" &&
|
|
117
|
-
"user" in value[0] && typeof value[0].user === "string");
|
|
118
|
-
}
|
|
@@ -1,79 +1,42 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
2
|
import { TransportError } from "../base.js";
|
|
3
|
-
|
|
4
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
3
|
+
import { AbortSignal_ } from "../_polyfills.js";
|
|
5
4
|
|
|
6
5
|
/** Configuration options for the `ReconnectingWebSocket`. */
|
|
7
6
|
export interface ReconnectingWebSocketOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Custom WebSocket constructor.
|
|
9
|
+
* @defaultValue The global `WebSocket` constructor.
|
|
10
|
+
*/
|
|
11
|
+
WebSocket?: new (url: string | URL, protocols?: string | string[]) => WebSocket;
|
|
8
12
|
/**
|
|
9
13
|
* Maximum number of reconnection attempts.
|
|
10
14
|
* @defaultValue `3`
|
|
11
15
|
*/
|
|
12
16
|
maxRetries?: number;
|
|
13
|
-
|
|
14
17
|
/**
|
|
15
18
|
* Maximum time in ms to wait for a connection to open.
|
|
16
19
|
* Set to `null` to disable.
|
|
17
20
|
* @defaultValue `10_000`
|
|
18
21
|
*/
|
|
19
22
|
connectionTimeout?: number | null;
|
|
20
|
-
|
|
21
23
|
/**
|
|
22
|
-
* Delay
|
|
24
|
+
* Delay before reconnection in ms.
|
|
23
25
|
* May be a number or a function that returns a number.
|
|
24
26
|
* @param attempt - The current attempt number.
|
|
25
27
|
* @defaultValue `(attempt) => Math.min(~~(1 << attempt) * 150, 10_000)` - Exponential backoff (max 10s)
|
|
26
28
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Custom logic to determine if reconnection is required.
|
|
31
|
-
* @param event - The close event that occurred during the connection.
|
|
32
|
-
* @returns A boolean indicating if reconnection should be attempted.
|
|
33
|
-
* @defaultValue `() => true` - Always reconnect
|
|
34
|
-
*/
|
|
35
|
-
shouldReconnect?: (event: CloseEvent, signal: AbortSignal) => MaybePromise<boolean>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Message buffering strategy between reconnection attempts.
|
|
39
|
-
* @defaultValue `new FIFOMessageBuffer()`
|
|
40
|
-
*/
|
|
41
|
-
messageBuffer?: MessageBufferStrategy;
|
|
29
|
+
reconnectionDelay?: number | ((attempt: number) => number);
|
|
42
30
|
}
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
export interface MessageBufferStrategy {
|
|
46
|
-
push(data: string | ArrayBufferLike | Blob | ArrayBufferView, signal?: AbortSignal): void;
|
|
47
|
-
[Symbol.iterator](): Iterator<string | ArrayBufferLike | Blob | ArrayBufferView>;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** Simple FIFO (First In, First Out) buffer implementation. */
|
|
51
|
-
class FIFOMessageBuffer implements MessageBufferStrategy {
|
|
52
|
-
queue: {
|
|
53
|
-
data: string | ArrayBufferLike | Blob | ArrayBufferView;
|
|
54
|
-
signal?: AbortSignal;
|
|
55
|
-
}[] = [];
|
|
56
|
-
|
|
57
|
-
push(data: string | ArrayBufferLike | Blob | ArrayBufferView, signal?: AbortSignal): void {
|
|
58
|
-
this.queue.push({ data, signal });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
*[Symbol.iterator](): Iterator<string | ArrayBufferLike | Blob | ArrayBufferView> {
|
|
62
|
-
while (this.queue.length > 0) {
|
|
63
|
-
const { data, signal } = this.queue.shift()!;
|
|
64
|
-
if (signal?.aborted) continue;
|
|
65
|
-
yield data;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
32
|
+
type WebSocketSendData = string | ArrayBufferLike | Blob | ArrayBufferView;
|
|
69
33
|
|
|
70
34
|
/** Error thrown when reconnection problems occur. */
|
|
71
35
|
export class ReconnectingWebSocketError extends TransportError {
|
|
72
36
|
constructor(
|
|
73
37
|
public code:
|
|
74
|
-
| "
|
|
75
|
-
| "
|
|
76
|
-
| "USER_INITIATED_CLOSE"
|
|
38
|
+
| "RECONNECTION_LIMIT"
|
|
39
|
+
| "TERMINATED_BY_USER"
|
|
77
40
|
| "UNKNOWN_ERROR",
|
|
78
41
|
cause?: unknown,
|
|
79
42
|
) {
|
|
@@ -84,8 +47,12 @@ export class ReconnectingWebSocketError extends TransportError {
|
|
|
84
47
|
}
|
|
85
48
|
|
|
86
49
|
/**
|
|
87
|
-
* A WebSocket that automatically reconnects
|
|
50
|
+
* A WebSocket that automatically reconnects and restores event listeners after disconnection.
|
|
88
51
|
* Fully compatible with standard WebSocket API.
|
|
52
|
+
*
|
|
53
|
+
* Additions:
|
|
54
|
+
* - `reconnectOptions` property: The options used to configure the reconnection behavior.
|
|
55
|
+
* - `terminateSignal` property: An `AbortSignal` that is aborted when the instance is permanently closed.
|
|
89
56
|
*/
|
|
90
57
|
export class ReconnectingWebSocket implements WebSocket {
|
|
91
58
|
protected _socket: WebSocket;
|
|
@@ -97,107 +64,135 @@ export class ReconnectingWebSocket implements WebSocket {
|
|
|
97
64
|
listenerProxy: EventListenerOrEventListenerObject;
|
|
98
65
|
}[] = [];
|
|
99
66
|
protected _attempt = 0;
|
|
67
|
+
protected _messageBuffer: { data: WebSocketSendData; signal?: AbortSignal }[] = [];
|
|
68
|
+
protected _abortController = new AbortController();
|
|
69
|
+
|
|
100
70
|
reconnectOptions: Required<ReconnectingWebSocketOptions>;
|
|
101
|
-
readonly
|
|
71
|
+
readonly terminateSignal = this._abortController.signal;
|
|
72
|
+
|
|
73
|
+
constructor(url: string | URL, options?: ReconnectingWebSocketOptions);
|
|
74
|
+
constructor(url: string | URL, protocols?: string | string[], options?: ReconnectingWebSocketOptions);
|
|
75
|
+
constructor(
|
|
76
|
+
url: string | URL,
|
|
77
|
+
protocolsOrOptions?: (string | string[]) | ReconnectingWebSocketOptions,
|
|
78
|
+
maybeOptions?: ReconnectingWebSocketOptions,
|
|
79
|
+
) {
|
|
80
|
+
const protocols = typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions)
|
|
81
|
+
? protocolsOrOptions
|
|
82
|
+
: undefined;
|
|
83
|
+
const options = typeof protocolsOrOptions === "object" && !Array.isArray(protocolsOrOptions)
|
|
84
|
+
? protocolsOrOptions
|
|
85
|
+
: maybeOptions;
|
|
86
|
+
|
|
87
|
+
if (!globalThis.WebSocket && !options?.WebSocket) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
"No WebSocket implementation found. Please provide a custom WebSocket constructor in the options.",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
102
92
|
|
|
103
|
-
constructor(url: string | URL, protocols?: string | string[], options?: ReconnectingWebSocketOptions) {
|
|
104
93
|
this.reconnectOptions = {
|
|
94
|
+
WebSocket: options?.WebSocket ?? WebSocket,
|
|
105
95
|
maxRetries: options?.maxRetries ?? 3,
|
|
106
96
|
connectionTimeout: options?.connectionTimeout === undefined ? 10_000 : options.connectionTimeout,
|
|
107
|
-
|
|
108
|
-
shouldReconnect: options?.shouldReconnect ?? (() => true),
|
|
109
|
-
messageBuffer: options?.messageBuffer ?? new FIFOMessageBuffer(),
|
|
97
|
+
reconnectionDelay: options?.reconnectionDelay ?? ((n) => Math.min(~~(1 << n) * 150, 10_000)),
|
|
110
98
|
};
|
|
111
99
|
|
|
112
100
|
this._socket = this._createSocket(url, protocols);
|
|
113
101
|
this._protocols = protocols;
|
|
114
|
-
|
|
102
|
+
|
|
103
|
+
this._initInternalListeners();
|
|
115
104
|
}
|
|
116
105
|
|
|
117
106
|
protected _createSocket(url: string | URL, protocols?: string | string[]): WebSocket {
|
|
118
|
-
const socket = new WebSocket(url, protocols);
|
|
107
|
+
const socket = new this.reconnectOptions.WebSocket(url, protocols);
|
|
119
108
|
if (this.reconnectOptions.connectionTimeout === null) return socket;
|
|
120
109
|
|
|
121
|
-
const
|
|
122
|
-
socket.removeEventListener("
|
|
123
|
-
socket.removeEventListener("
|
|
124
|
-
|
|
125
|
-
}, this.reconnectOptions.connectionTimeout);
|
|
126
|
-
|
|
127
|
-
const openHandler = () => {
|
|
128
|
-
socket.removeEventListener("close", closeHandler);
|
|
129
|
-
clearTimeout(timeoutId);
|
|
110
|
+
const handleOpen = () => {
|
|
111
|
+
socket.removeEventListener("close", handleClose);
|
|
112
|
+
socket.removeEventListener("error", handleError);
|
|
113
|
+
signal.removeEventListener("abort", handleAbort);
|
|
130
114
|
};
|
|
131
|
-
const
|
|
132
|
-
socket.removeEventListener("open",
|
|
133
|
-
|
|
115
|
+
const handleClose = () => {
|
|
116
|
+
socket.removeEventListener("open", handleOpen);
|
|
117
|
+
socket.removeEventListener("error", handleError);
|
|
118
|
+
signal.removeEventListener("abort", handleAbort);
|
|
134
119
|
};
|
|
120
|
+
const handleError = () => {
|
|
121
|
+
socket.removeEventListener("open", handleOpen);
|
|
122
|
+
socket.removeEventListener("close", handleClose);
|
|
123
|
+
signal.removeEventListener("abort", handleAbort);
|
|
124
|
+
};
|
|
125
|
+
const handleAbort = () => {
|
|
126
|
+
socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const signal = AbortSignal_.timeout(this.reconnectOptions.connectionTimeout);
|
|
135
130
|
|
|
136
|
-
socket.addEventListener("open",
|
|
137
|
-
socket.addEventListener("close",
|
|
131
|
+
socket.addEventListener("open", handleOpen, { once: true, signal });
|
|
132
|
+
socket.addEventListener("close", handleClose, { once: true, signal });
|
|
133
|
+
socket.addEventListener("error", handleError, { once: true, signal });
|
|
134
|
+
signal.addEventListener("abort", handleAbort, { once: true });
|
|
138
135
|
|
|
139
136
|
return socket;
|
|
140
137
|
}
|
|
141
138
|
|
|
139
|
+
protected _cleanup(code: ConstructorParameters<typeof ReconnectingWebSocketError>[0], cause?: unknown) {
|
|
140
|
+
const error = new ReconnectingWebSocketError(code, cause);
|
|
141
|
+
this._abortController.abort(error);
|
|
142
|
+
this._listeners = [];
|
|
143
|
+
this._socket.close();
|
|
144
|
+
}
|
|
145
|
+
|
|
142
146
|
/** Initializes the internal event listeners for the socket. */
|
|
143
|
-
protected
|
|
147
|
+
protected _initInternalListeners() {
|
|
148
|
+
const handleClose = () => {
|
|
149
|
+
this._socket.removeEventListener("error", handleError);
|
|
150
|
+
this._close();
|
|
151
|
+
};
|
|
152
|
+
const handleError = () => {
|
|
153
|
+
this._socket.removeEventListener("close", handleClose);
|
|
154
|
+
this._close();
|
|
155
|
+
};
|
|
144
156
|
this._socket.addEventListener("open", this._open, { once: true });
|
|
145
|
-
this._socket.addEventListener("close",
|
|
157
|
+
this._socket.addEventListener("close", handleClose, { once: true });
|
|
158
|
+
this._socket.addEventListener("error", handleError, { once: true });
|
|
146
159
|
}
|
|
147
160
|
protected _open: () => void = () => {
|
|
148
161
|
// Reset the attempt counter
|
|
149
162
|
this._attempt = 0;
|
|
150
163
|
|
|
151
164
|
// Send all buffered messages
|
|
152
|
-
|
|
153
|
-
this.
|
|
165
|
+
while (this._messageBuffer.length > 0) {
|
|
166
|
+
const item = this._messageBuffer.shift()!;
|
|
167
|
+
if (item.signal?.aborted) continue;
|
|
168
|
+
this._socket.send(item.data);
|
|
154
169
|
}
|
|
155
170
|
};
|
|
156
|
-
protected _close = async (
|
|
171
|
+
protected _close = async () => {
|
|
157
172
|
try {
|
|
158
|
-
// If the event was triggered but the socket is not closing, ignore it
|
|
159
|
-
if (
|
|
160
|
-
this._socket.readyState !== ReconnectingWebSocket.CLOSING &&
|
|
161
|
-
this._socket.readyState !== ReconnectingWebSocket.CLOSED
|
|
162
|
-
) return;
|
|
163
|
-
|
|
164
173
|
// If the instance is terminated, do not attempt to reconnect
|
|
165
|
-
if (this.
|
|
174
|
+
if (this._abortController.signal.aborted) return;
|
|
166
175
|
|
|
167
176
|
// Check if reconnection should be attempted
|
|
168
177
|
if (++this._attempt > this.reconnectOptions.maxRetries) {
|
|
169
|
-
this._cleanup("
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const userDecision = await this.reconnectOptions.shouldReconnect(
|
|
174
|
-
event,
|
|
175
|
-
this.reconnectAbortController.signal,
|
|
176
|
-
);
|
|
177
|
-
if (this.reconnectAbortController.signal.aborted) return;
|
|
178
|
-
if (!userDecision) {
|
|
179
|
-
this._cleanup("RECONNECTION_STOPPED_BY_USER");
|
|
178
|
+
this._cleanup("RECONNECTION_LIMIT");
|
|
180
179
|
return;
|
|
181
180
|
}
|
|
182
181
|
|
|
183
182
|
// Delay before reconnecting
|
|
184
|
-
const
|
|
185
|
-
? this.reconnectOptions.
|
|
186
|
-
:
|
|
187
|
-
|
|
188
|
-
await delay(reconnectDelay, this.reconnectAbortController.signal);
|
|
189
|
-
|
|
190
|
-
// Create a new WebSocket instance
|
|
191
|
-
const { onclose, onerror, onmessage, onopen } = this._socket;
|
|
192
|
-
this._socket = this._createSocket(this._socket.url, this._protocols);
|
|
183
|
+
const delay = typeof this.reconnectOptions.reconnectionDelay === "number"
|
|
184
|
+
? this.reconnectOptions.reconnectionDelay
|
|
185
|
+
: this.reconnectOptions.reconnectionDelay(this._attempt);
|
|
186
|
+
await sleep(delay, this._abortController.signal);
|
|
193
187
|
|
|
194
|
-
//
|
|
195
|
-
this.
|
|
188
|
+
// Create a new WebSocket instance and re-apply event listeners
|
|
189
|
+
const { onclose, onerror, onmessage, onopen } = this._socket; // preserve event handlers
|
|
190
|
+
this._socket = this._createSocket(this._socket.url, this._protocols);
|
|
196
191
|
|
|
192
|
+
this._initInternalListeners();
|
|
197
193
|
this._listeners.forEach(({ type, listenerProxy, options }) => {
|
|
198
194
|
this._socket.addEventListener(type, listenerProxy, options);
|
|
199
195
|
});
|
|
200
|
-
|
|
201
196
|
this._socket.onclose = onclose;
|
|
202
197
|
this._socket.onerror = onerror;
|
|
203
198
|
this._socket.onmessage = onmessage;
|
|
@@ -207,13 +202,6 @@ export class ReconnectingWebSocket implements WebSocket {
|
|
|
207
202
|
}
|
|
208
203
|
};
|
|
209
204
|
|
|
210
|
-
/** Clean up internal resources. */
|
|
211
|
-
protected _cleanup(code: ConstructorParameters<typeof ReconnectingWebSocketError>[0], cause?: unknown) {
|
|
212
|
-
this.reconnectAbortController.abort(new ReconnectingWebSocketError(code, cause));
|
|
213
|
-
this._listeners = [];
|
|
214
|
-
this._socket.close();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
205
|
// WebSocket property implementations
|
|
218
206
|
get url(): string {
|
|
219
207
|
return this._socket.url;
|
|
@@ -280,17 +268,17 @@ export class ReconnectingWebSocket implements WebSocket {
|
|
|
280
268
|
*/
|
|
281
269
|
close(code?: number, reason?: string, permanently: boolean = true): void {
|
|
282
270
|
this._socket.close(code, reason);
|
|
283
|
-
if (permanently) this._cleanup("
|
|
271
|
+
if (permanently) this._cleanup("TERMINATED_BY_USER");
|
|
284
272
|
}
|
|
285
273
|
|
|
286
274
|
/**
|
|
287
275
|
* @param signal - `AbortSignal` to cancel sending a message if it was in the buffer.
|
|
288
276
|
* @note If the connection is not open, the data will be buffered and sent when the connection is established.
|
|
289
277
|
*/
|
|
290
|
-
send(data:
|
|
278
|
+
send(data: WebSocketSendData, signal?: AbortSignal): void {
|
|
291
279
|
if (signal?.aborted) return;
|
|
292
|
-
if (this._socket.readyState !== ReconnectingWebSocket.OPEN && !this.
|
|
293
|
-
this.
|
|
280
|
+
if (this._socket.readyState !== ReconnectingWebSocket.OPEN && !this._abortController.signal.aborted) {
|
|
281
|
+
this._messageBuffer.push({ data, signal });
|
|
294
282
|
} else {
|
|
295
283
|
this._socket.send(data);
|
|
296
284
|
}
|
|
@@ -310,7 +298,7 @@ export class ReconnectingWebSocket implements WebSocket {
|
|
|
310
298
|
): void {
|
|
311
299
|
// Wrap the listener to handle reconnection
|
|
312
300
|
let listenerProxy: EventListenerOrEventListenerObject;
|
|
313
|
-
if (this.
|
|
301
|
+
if (this._abortController.signal.aborted) {
|
|
314
302
|
// If the instance is terminated, use the original listener
|
|
315
303
|
listenerProxy = listener;
|
|
316
304
|
} else {
|
|
@@ -381,13 +369,13 @@ function listenersMatch(
|
|
|
381
369
|
a: { type: string; listener: EventListenerOrEventListenerObject; options?: boolean | AddEventListenerOptions },
|
|
382
370
|
b: { type: string; listener: EventListenerOrEventListenerObject; options?: boolean | AddEventListenerOptions },
|
|
383
371
|
): boolean {
|
|
384
|
-
// EventTarget only compares capture in options, even if one is an object and the other is boolean
|
|
372
|
+
// `EventTarget` only compares `capture` in options, even if one is an object and the other is boolean
|
|
385
373
|
const aCapture = Boolean(typeof a.options === "object" ? a.options.capture : a.options);
|
|
386
374
|
const bCapture = Boolean(typeof b.options === "object" ? b.options.capture : b.options);
|
|
387
375
|
return a.type === b.type && a.listener === b.listener && aCapture === bCapture;
|
|
388
376
|
}
|
|
389
377
|
|
|
390
|
-
function
|
|
378
|
+
function sleep(ms: number, signal?: AbortSignal): Promise<void> {
|
|
391
379
|
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
392
380
|
return new Promise((resolve, reject) => {
|
|
393
381
|
const onAbort = () => {
|