@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.
Files changed (329) hide show
  1. package/README.md +114 -106
  2. package/esm/bin/_utils.d.ts +80 -0
  3. package/esm/bin/_utils.d.ts.map +1 -0
  4. package/esm/bin/_utils.js +112 -0
  5. package/esm/bin/_utils.js.map +1 -0
  6. package/esm/bin/cli.d.ts +3 -0
  7. package/esm/bin/cli.d.ts.map +1 -0
  8. package/esm/bin/cli.js +334 -0
  9. package/esm/bin/cli.js.map +1 -0
  10. package/esm/src/{errors.d.ts → _errors.d.ts} +1 -1
  11. package/esm/src/_errors.d.ts.map +1 -0
  12. package/esm/src/{errors.js → _errors.js} +1 -1
  13. package/esm/src/_errors.js.map +1 -0
  14. package/esm/src/clients/exchange.d.ts +91 -91
  15. package/esm/src/clients/exchange.d.ts.map +1 -1
  16. package/esm/src/clients/exchange.js +61 -56
  17. package/esm/src/clients/exchange.js.map +1 -1
  18. package/esm/src/clients/info.d.ts +134 -112
  19. package/esm/src/clients/info.d.ts.map +1 -1
  20. package/esm/src/clients/info.js +95 -72
  21. package/esm/src/clients/info.js.map +1 -1
  22. package/esm/src/clients/multiSign.d.ts +2 -2
  23. package/esm/src/clients/multiSign.d.ts.map +1 -1
  24. package/esm/src/clients/multiSign.js +3 -1
  25. package/esm/src/clients/multiSign.js.map +1 -1
  26. package/esm/src/clients/subscription.d.ts +23 -23
  27. package/esm/src/clients/subscription.d.ts.map +1 -1
  28. package/esm/src/clients/subscription.js +8 -11
  29. package/esm/src/clients/subscription.js.map +1 -1
  30. package/esm/src/mod.d.ts +21 -0
  31. package/esm/src/mod.d.ts.map +1 -0
  32. package/esm/src/mod.js +14 -0
  33. package/esm/src/mod.js.map +1 -0
  34. package/esm/src/schemas/_base.d.ts +8 -6
  35. package/esm/src/schemas/_base.d.ts.map +1 -1
  36. package/esm/src/schemas/_base.js +6 -4
  37. package/esm/src/schemas/_base.js.map +1 -1
  38. package/esm/src/schemas/exchange/requests.d.ts +332 -313
  39. package/esm/src/schemas/exchange/requests.d.ts.map +1 -1
  40. package/esm/src/schemas/exchange/requests.js +52 -61
  41. package/esm/src/schemas/exchange/requests.js.map +1 -1
  42. package/esm/src/schemas/exchange/responses.d.ts +10 -10
  43. package/esm/src/schemas/exchange/responses.js +3 -3
  44. package/esm/src/schemas/exchange/responses.js.map +1 -1
  45. package/esm/src/schemas/explorer/requests.d.ts +1 -1
  46. package/esm/src/schemas/explorer/requests.js +2 -2
  47. package/esm/src/schemas/explorer/requests.js.map +1 -1
  48. package/esm/src/schemas/explorer/responses.d.ts +16 -16
  49. package/esm/src/schemas/explorer/responses.js +3 -3
  50. package/esm/src/schemas/explorer/responses.js.map +1 -1
  51. package/esm/src/schemas/info/accounts.d.ts +975 -229
  52. package/esm/src/schemas/info/accounts.d.ts.map +1 -1
  53. package/esm/src/schemas/info/accounts.js +65 -21
  54. package/esm/src/schemas/info/accounts.js.map +1 -1
  55. package/esm/src/schemas/info/assets.d.ts +110 -110
  56. package/esm/src/schemas/info/assets.js +9 -9
  57. package/esm/src/schemas/info/assets.js.map +1 -1
  58. package/esm/src/schemas/info/markets.d.ts +25 -25
  59. package/esm/src/schemas/info/markets.js +3 -3
  60. package/esm/src/schemas/info/markets.js.map +1 -1
  61. package/esm/src/schemas/info/orders.d.ts +175 -175
  62. package/esm/src/schemas/info/orders.js +3 -3
  63. package/esm/src/schemas/info/orders.js.map +1 -1
  64. package/esm/src/schemas/info/requests.d.ts +31 -16
  65. package/esm/src/schemas/info/requests.d.ts.map +1 -1
  66. package/esm/src/schemas/info/requests.js +51 -40
  67. package/esm/src/schemas/info/requests.js.map +1 -1
  68. package/esm/src/schemas/info/validators.d.ts +30 -30
  69. package/esm/src/schemas/info/validators.d.ts.map +1 -1
  70. package/esm/src/schemas/info/validators.js +8 -8
  71. package/esm/src/schemas/info/validators.js.map +1 -1
  72. package/esm/src/schemas/info/vaults.d.ts +46 -46
  73. package/esm/src/schemas/info/vaults.js +10 -10
  74. package/esm/src/schemas/info/vaults.js.map +1 -1
  75. package/esm/src/schemas/mod.d.ts +3 -3
  76. package/esm/src/schemas/mod.d.ts.map +1 -1
  77. package/esm/src/schemas/mod.js +3 -3
  78. package/esm/src/schemas/mod.js.map +1 -1
  79. package/esm/src/schemas/subscriptions/requests.d.ts +4 -4
  80. package/esm/src/schemas/subscriptions/requests.d.ts.map +1 -1
  81. package/esm/src/schemas/subscriptions/requests.js +17 -17
  82. package/esm/src/schemas/subscriptions/requests.js.map +1 -1
  83. package/esm/src/schemas/subscriptions/responses.d.ts +618 -618
  84. package/esm/src/schemas/subscriptions/responses.js +14 -14
  85. package/esm/src/schemas/subscriptions/responses.js.map +1 -1
  86. package/esm/src/signing/mod.d.ts +1 -1
  87. package/esm/src/signing/mod.d.ts.map +1 -1
  88. package/esm/src/signing/mod.js +6 -6
  89. package/esm/src/signing/mod.js.map +1 -1
  90. package/esm/src/signing/signTypedData/ethers.d.ts.map +1 -0
  91. package/esm/src/signing/signTypedData/ethers.js.map +1 -0
  92. package/esm/src/signing/signTypedData/mod.d.ts.map +1 -0
  93. package/esm/src/signing/signTypedData/mod.js.map +1 -0
  94. package/esm/src/signing/signTypedData/private_key.d.ts.map +1 -0
  95. package/esm/src/signing/{_signTypedData → signTypedData}/private_key.js +18 -17
  96. package/esm/src/signing/signTypedData/private_key.js.map +1 -0
  97. package/esm/src/signing/signTypedData/viem.d.ts.map +1 -0
  98. package/esm/src/signing/signTypedData/viem.js.map +1 -0
  99. package/esm/src/transports/_polyfills.d.ts +12 -0
  100. package/esm/src/transports/_polyfills.d.ts.map +1 -0
  101. package/esm/src/transports/_polyfills.js +40 -0
  102. package/esm/src/transports/_polyfills.js.map +1 -0
  103. package/esm/src/transports/base.d.ts +8 -8
  104. package/esm/src/transports/base.d.ts.map +1 -1
  105. package/esm/src/transports/base.js +2 -2
  106. package/esm/src/transports/base.js.map +1 -1
  107. package/esm/src/transports/http/http_transport.d.ts +11 -4
  108. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  109. package/esm/src/transports/http/http_transport.js +17 -6
  110. package/esm/src/transports/http/http_transport.js.map +1 -1
  111. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
  112. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  113. package/esm/src/transports/websocket/_hyperliquid_event_target.js +14 -33
  114. package/esm/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
  115. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
  116. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  117. package/esm/src/transports/websocket/_reconnecting_websocket.js +82 -76
  118. package/esm/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
  119. package/esm/src/transports/websocket/_websocket_async_request.d.ts +6 -0
  120. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  121. package/esm/src/transports/websocket/_websocket_async_request.js +49 -41
  122. package/esm/src/transports/websocket/_websocket_async_request.js.map +1 -1
  123. package/esm/src/transports/websocket/websocket_transport.d.ts +48 -70
  124. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  125. package/esm/src/transports/websocket/websocket_transport.js +90 -103
  126. package/esm/src/transports/websocket/websocket_transport.js.map +1 -1
  127. package/package.json +12 -8
  128. package/script/bin/_utils.d.ts +80 -0
  129. package/script/bin/_utils.d.ts.map +1 -0
  130. package/script/bin/_utils.js +116 -0
  131. package/script/bin/_utils.js.map +1 -0
  132. package/script/bin/cli.d.ts +3 -0
  133. package/script/bin/cli.d.ts.map +1 -0
  134. package/script/bin/cli.js +369 -0
  135. package/script/bin/cli.js.map +1 -0
  136. package/script/src/{errors.d.ts → _errors.d.ts} +1 -1
  137. package/script/src/_errors.d.ts.map +1 -0
  138. package/script/src/{errors.js → _errors.js} +1 -1
  139. package/script/src/_errors.js.map +1 -0
  140. package/script/src/clients/exchange.d.ts +91 -91
  141. package/script/src/clients/exchange.d.ts.map +1 -1
  142. package/script/src/clients/exchange.js +61 -56
  143. package/script/src/clients/exchange.js.map +1 -1
  144. package/script/src/clients/info.d.ts +134 -112
  145. package/script/src/clients/info.d.ts.map +1 -1
  146. package/script/src/clients/info.js +94 -71
  147. package/script/src/clients/info.js.map +1 -1
  148. package/script/src/clients/multiSign.d.ts +2 -2
  149. package/script/src/clients/multiSign.d.ts.map +1 -1
  150. package/script/src/clients/multiSign.js +9 -7
  151. package/script/src/clients/multiSign.js.map +1 -1
  152. package/script/src/clients/subscription.d.ts +23 -23
  153. package/script/src/clients/subscription.d.ts.map +1 -1
  154. package/script/src/clients/subscription.js +8 -11
  155. package/script/src/clients/subscription.js.map +1 -1
  156. package/script/src/mod.d.ts +21 -0
  157. package/script/src/mod.d.ts.map +1 -0
  158. package/script/{mod.js → src/mod.js} +12 -8
  159. package/script/src/mod.js.map +1 -0
  160. package/script/src/schemas/_base.d.ts +8 -6
  161. package/script/src/schemas/_base.d.ts.map +1 -1
  162. package/script/src/schemas/_base.js +7 -5
  163. package/script/src/schemas/_base.js.map +1 -1
  164. package/script/src/schemas/exchange/requests.d.ts +332 -313
  165. package/script/src/schemas/exchange/requests.d.ts.map +1 -1
  166. package/script/src/schemas/exchange/requests.js +51 -60
  167. package/script/src/schemas/exchange/requests.js.map +1 -1
  168. package/script/src/schemas/exchange/responses.d.ts +10 -10
  169. package/script/src/schemas/exchange/responses.js +2 -2
  170. package/script/src/schemas/exchange/responses.js.map +1 -1
  171. package/script/src/schemas/explorer/requests.d.ts +1 -1
  172. package/script/src/schemas/explorer/requests.js +1 -1
  173. package/script/src/schemas/explorer/requests.js.map +1 -1
  174. package/script/src/schemas/explorer/responses.d.ts +16 -16
  175. package/script/src/schemas/explorer/responses.js +2 -2
  176. package/script/src/schemas/explorer/responses.js.map +1 -1
  177. package/script/src/schemas/info/accounts.d.ts +975 -229
  178. package/script/src/schemas/info/accounts.d.ts.map +1 -1
  179. package/script/src/schemas/info/accounts.js +65 -21
  180. package/script/src/schemas/info/accounts.js.map +1 -1
  181. package/script/src/schemas/info/assets.d.ts +110 -110
  182. package/script/src/schemas/info/assets.js +8 -8
  183. package/script/src/schemas/info/assets.js.map +1 -1
  184. package/script/src/schemas/info/markets.d.ts +25 -25
  185. package/script/src/schemas/info/markets.js +2 -2
  186. package/script/src/schemas/info/markets.js.map +1 -1
  187. package/script/src/schemas/info/orders.d.ts +175 -175
  188. package/script/src/schemas/info/orders.js +2 -2
  189. package/script/src/schemas/info/orders.js.map +1 -1
  190. package/script/src/schemas/info/requests.d.ts +31 -16
  191. package/script/src/schemas/info/requests.d.ts.map +1 -1
  192. package/script/src/schemas/info/requests.js +51 -40
  193. package/script/src/schemas/info/requests.js.map +1 -1
  194. package/script/src/schemas/info/validators.d.ts +30 -30
  195. package/script/src/schemas/info/validators.d.ts.map +1 -1
  196. package/script/src/schemas/info/validators.js +7 -7
  197. package/script/src/schemas/info/validators.js.map +1 -1
  198. package/script/src/schemas/info/vaults.d.ts +46 -46
  199. package/script/src/schemas/info/vaults.js +9 -9
  200. package/script/src/schemas/info/vaults.js.map +1 -1
  201. package/script/src/schemas/mod.d.ts +3 -3
  202. package/script/src/schemas/mod.d.ts.map +1 -1
  203. package/script/src/schemas/mod.js +4 -4
  204. package/script/src/schemas/mod.js.map +1 -1
  205. package/script/src/schemas/subscriptions/requests.d.ts +4 -4
  206. package/script/src/schemas/subscriptions/requests.d.ts.map +1 -1
  207. package/script/src/schemas/subscriptions/requests.js +16 -16
  208. package/script/src/schemas/subscriptions/requests.js.map +1 -1
  209. package/script/src/schemas/subscriptions/responses.d.ts +618 -618
  210. package/script/src/schemas/subscriptions/responses.js +13 -13
  211. package/script/src/schemas/subscriptions/responses.js.map +1 -1
  212. package/script/src/signing/mod.d.ts +1 -1
  213. package/script/src/signing/mod.d.ts.map +1 -1
  214. package/script/src/signing/mod.js +40 -7
  215. package/script/src/signing/mod.js.map +1 -1
  216. package/script/src/signing/signTypedData/ethers.d.ts.map +1 -0
  217. package/script/src/signing/signTypedData/ethers.js.map +1 -0
  218. package/script/src/signing/signTypedData/mod.d.ts.map +1 -0
  219. package/script/src/signing/signTypedData/mod.js.map +1 -0
  220. package/script/src/signing/signTypedData/private_key.d.ts.map +1 -0
  221. package/script/src/signing/{_signTypedData → signTypedData}/private_key.js +55 -21
  222. package/script/src/signing/signTypedData/private_key.js.map +1 -0
  223. package/script/src/signing/signTypedData/viem.d.ts.map +1 -0
  224. package/script/src/signing/signTypedData/viem.js.map +1 -0
  225. package/script/src/transports/_polyfills.d.ts +12 -0
  226. package/script/src/transports/_polyfills.d.ts.map +1 -0
  227. package/script/src/transports/_polyfills.js +43 -0
  228. package/script/src/transports/_polyfills.js.map +1 -0
  229. package/script/src/transports/base.d.ts +8 -8
  230. package/script/src/transports/base.d.ts.map +1 -1
  231. package/script/src/transports/base.js +3 -3
  232. package/script/src/transports/base.js.map +1 -1
  233. package/script/src/transports/http/http_transport.d.ts +11 -4
  234. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  235. package/script/src/transports/http/http_transport.js +17 -6
  236. package/script/src/transports/http/http_transport.js.map +1 -1
  237. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
  238. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  239. package/script/src/transports/websocket/_hyperliquid_event_target.js +47 -33
  240. package/script/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
  241. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
  242. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  243. package/script/src/transports/websocket/_reconnecting_websocket.js +82 -76
  244. package/script/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
  245. package/script/src/transports/websocket/_websocket_async_request.d.ts +6 -0
  246. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  247. package/script/src/transports/websocket/_websocket_async_request.js +52 -43
  248. package/script/src/transports/websocket/_websocket_async_request.js.map +1 -1
  249. package/script/src/transports/websocket/websocket_transport.d.ts +48 -70
  250. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  251. package/script/src/transports/websocket/websocket_transport.js +92 -105
  252. package/script/src/transports/websocket/websocket_transport.js.map +1 -1
  253. package/src/bin/_utils.ts +185 -0
  254. package/src/bin/cli.ts +359 -0
  255. package/src/src/clients/exchange.ts +155 -144
  256. package/src/src/clients/info.ts +158 -124
  257. package/src/src/clients/multiSign.ts +13 -11
  258. package/src/src/clients/subscription.ts +32 -32
  259. package/src/src/mod.ts +29 -0
  260. package/src/src/schemas/_base.ts +25 -8
  261. package/src/src/schemas/exchange/requests.ts +59 -61
  262. package/src/src/schemas/exchange/responses.ts +3 -3
  263. package/src/src/schemas/explorer/requests.ts +2 -2
  264. package/src/src/schemas/explorer/responses.ts +3 -3
  265. package/src/src/schemas/info/accounts.ts +129 -21
  266. package/src/src/schemas/info/assets.ts +9 -9
  267. package/src/src/schemas/info/markets.ts +3 -3
  268. package/src/src/schemas/info/orders.ts +3 -3
  269. package/src/src/schemas/info/requests.ts +72 -40
  270. package/src/src/schemas/info/validators.ts +22 -24
  271. package/src/src/schemas/info/vaults.ts +10 -10
  272. package/src/src/schemas/mod.ts +3 -3
  273. package/src/src/schemas/subscriptions/requests.ts +27 -17
  274. package/src/src/schemas/subscriptions/responses.ts +14 -14
  275. package/src/src/signing/mod.ts +6 -6
  276. package/src/src/signing/{_signTypedData → signTypedData}/private_key.ts +22 -17
  277. package/src/src/transports/_polyfills.ts +41 -0
  278. package/src/src/transports/base.ts +8 -8
  279. package/src/src/transports/http/http_transport.ts +25 -14
  280. package/src/src/transports/websocket/_hyperliquid_event_target.ts +24 -51
  281. package/src/src/transports/websocket/_reconnecting_websocket.ts +107 -119
  282. package/src/src/transports/websocket/_websocket_async_request.ts +57 -59
  283. package/src/src/transports/websocket/websocket_transport.ts +126 -167
  284. package/esm/mod.d.ts +0 -20
  285. package/esm/mod.d.ts.map +0 -1
  286. package/esm/mod.js +0 -12
  287. package/esm/mod.js.map +0 -1
  288. package/esm/src/errors.d.ts.map +0 -1
  289. package/esm/src/errors.js.map +0 -1
  290. package/esm/src/signing/_signTypedData/ethers.d.ts.map +0 -1
  291. package/esm/src/signing/_signTypedData/ethers.js.map +0 -1
  292. package/esm/src/signing/_signTypedData/mod.d.ts.map +0 -1
  293. package/esm/src/signing/_signTypedData/mod.js.map +0 -1
  294. package/esm/src/signing/_signTypedData/private_key.d.ts.map +0 -1
  295. package/esm/src/signing/_signTypedData/private_key.js.map +0 -1
  296. package/esm/src/signing/_signTypedData/viem.d.ts.map +0 -1
  297. package/esm/src/signing/_signTypedData/viem.js.map +0 -1
  298. package/script/mod.d.ts +0 -20
  299. package/script/mod.d.ts.map +0 -1
  300. package/script/mod.js.map +0 -1
  301. package/script/src/errors.d.ts.map +0 -1
  302. package/script/src/errors.js.map +0 -1
  303. package/script/src/signing/_signTypedData/ethers.d.ts.map +0 -1
  304. package/script/src/signing/_signTypedData/ethers.js.map +0 -1
  305. package/script/src/signing/_signTypedData/mod.d.ts.map +0 -1
  306. package/script/src/signing/_signTypedData/mod.js.map +0 -1
  307. package/script/src/signing/_signTypedData/private_key.d.ts.map +0 -1
  308. package/script/src/signing/_signTypedData/private_key.js.map +0 -1
  309. package/script/src/signing/_signTypedData/viem.d.ts.map +0 -1
  310. package/script/src/signing/_signTypedData/viem.js.map +0 -1
  311. package/src/mod.ts +0 -28
  312. /package/esm/src/signing/{_signTypedData → signTypedData}/ethers.d.ts +0 -0
  313. /package/esm/src/signing/{_signTypedData → signTypedData}/ethers.js +0 -0
  314. /package/esm/src/signing/{_signTypedData → signTypedData}/mod.d.ts +0 -0
  315. /package/esm/src/signing/{_signTypedData → signTypedData}/mod.js +0 -0
  316. /package/esm/src/signing/{_signTypedData → signTypedData}/private_key.d.ts +0 -0
  317. /package/esm/src/signing/{_signTypedData → signTypedData}/viem.d.ts +0 -0
  318. /package/esm/src/signing/{_signTypedData → signTypedData}/viem.js +0 -0
  319. /package/script/src/signing/{_signTypedData → signTypedData}/ethers.d.ts +0 -0
  320. /package/script/src/signing/{_signTypedData → signTypedData}/ethers.js +0 -0
  321. /package/script/src/signing/{_signTypedData → signTypedData}/mod.d.ts +0 -0
  322. /package/script/src/signing/{_signTypedData → signTypedData}/mod.js +0 -0
  323. /package/script/src/signing/{_signTypedData → signTypedData}/private_key.d.ts +0 -0
  324. /package/script/src/signing/{_signTypedData → signTypedData}/viem.d.ts +0 -0
  325. /package/script/src/signing/{_signTypedData → signTypedData}/viem.js +0 -0
  326. /package/src/src/{errors.ts → _errors.ts} +0 -0
  327. /package/src/src/signing/{_signTypedData → signTypedData}/ethers.ts +0 -0
  328. /package/src/src/signing/{_signTypedData → signTypedData}/mod.ts +0 -0
  329. /package/src/src/signing/{_signTypedData → signTypedData}/viem.ts +0 -0
@@ -1,18 +1,13 @@
1
- import type { BlockDetails, TxDetails } from "../../schemas/mod.js";
2
-
3
- /** Represents a message from the Hyperliquid WebSocket API. */
4
- interface HyperliquidMsg {
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 SubscriptionResponse {
13
- /** Type of subscription operation. */
7
+ interface SubscribeUnsubscribeResponse {
8
+ /** Type of response */
14
9
  method: "subscribe" | "unsubscribe";
15
- /** Original subscription request. */
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
- export interface HyperliquidEventMap {
60
- subscriptionResponse: CustomEvent<SubscriptionResponse>;
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 EventTarget {
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) as unknown;
77
- if (isHyperliquidMsg(msg)) {
78
- this.dispatchEvent(new CustomEvent(msg.channel, { detail: msg.data }));
79
- } else if (isExplorerBlockMsg(msg)) {
80
- this.dispatchEvent(new CustomEvent("_explorerBlock", { detail: msg }));
81
- } else if (isExplorerTxsMsg(msg)) {
82
- this.dispatchEvent(new CustomEvent("_explorerTxs", { detail: msg }));
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 between reconnection attempts in ms.
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
- connectionDelay?: number | ((attempt: number, signal: AbortSignal) => MaybePromise<number>);
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
- /** Message buffer strategy interface. */
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
- | "RECONNECTION_LIMIT_REACHED"
75
- | "RECONNECTION_STOPPED_BY_USER"
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 when disconnected.
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 reconnectAbortController: AbortController = new AbortController();
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
- connectionDelay: options?.connectionDelay ?? ((n) => Math.min(~~(1 << n) * 150, 10_000)),
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
- this._setupEventListeners();
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 timeoutId = setTimeout(() => {
122
- socket.removeEventListener("open", openHandler);
123
- socket.removeEventListener("close", closeHandler);
124
- socket.close(3008, "Timeout"); // https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
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 closeHandler = () => {
132
- socket.removeEventListener("open", openHandler);
133
- clearTimeout(timeoutId);
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", openHandler, { once: true });
137
- socket.addEventListener("close", closeHandler, { once: true });
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 _setupEventListeners() {
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", this._close, { once: true });
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
- for (const message of this.reconnectOptions.messageBuffer) {
153
- this._socket.send(message);
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 (event: CloseEvent) => {
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.reconnectAbortController.signal.aborted) return;
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("RECONNECTION_LIMIT_REACHED");
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 reconnectDelay = typeof this.reconnectOptions.connectionDelay === "number"
185
- ? this.reconnectOptions.connectionDelay
186
- : await this.reconnectOptions.connectionDelay(this._attempt, this.reconnectAbortController.signal);
187
- if (this.reconnectAbortController.signal.aborted) return;
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
- // Reconnect all listeners
195
- this._setupEventListeners();
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("USER_INITIATED_CLOSE");
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: string | ArrayBufferLike | Blob | ArrayBufferView, signal?: AbortSignal): void {
278
+ send(data: WebSocketSendData, signal?: AbortSignal): void {
291
279
  if (signal?.aborted) return;
292
- if (this._socket.readyState !== ReconnectingWebSocket.OPEN && !this.reconnectAbortController.signal.aborted) {
293
- this.reconnectOptions.messageBuffer.push(data, signal);
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.reconnectAbortController.signal.aborted) {
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 delay(ms: number, signal?: AbortSignal): Promise<void> {
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 = () => {