@pear-protocol/hyperliquid-sdk 0.0.13 → 0.0.15
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/dist/client.d.ts +10 -1
- package/dist/hooks/index.d.ts +7 -7
- package/dist/hooks/useBasketCandles.d.ts +12 -0
- package/dist/hooks/useHistoricalPriceData.d.ts +9 -0
- package/dist/hooks/useTokenSelectionMetadata.d.ts +14 -0
- package/dist/hooks/useTrading.d.ts +6 -6
- package/dist/hooks/useUserSelection.d.ts +2 -0
- package/dist/hooks/useWebData.d.ts +12 -0
- package/dist/hyperliquid-websocket.d.ts +3 -5
- package/dist/index.d.ts +161 -78
- package/dist/index.js +3539 -8
- package/dist/provider.d.ts +0 -22
- package/dist/store/historicalPriceDataStore.d.ts +14 -0
- package/dist/store/hyperliquidDataStore.d.ts +1 -0
- package/dist/store/tokenSelectionMetadataStore.d.ts +21 -0
- package/dist/store/userDataStore.d.ts +1 -0
- package/dist/{hooks/useTokenSelection.d.ts → store/userSelection.d.ts} +11 -20
- package/dist/types.d.ts +55 -2
- package/dist/utils/basket-calculator.d.ts +24 -0
- package/dist/websocket.d.ts +2 -12
- package/package.json +1 -1
- package/dist/hooks/use-webdata2.d.ts +0 -10
- package/dist/hooks/useCalculatedAccountSummary.d.ts +0 -5
- package/dist/hooks/useCalculatedPositions.d.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -1,4 +1,262 @@
|
|
|
1
|
-
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import require$$0, { useState, useEffect, useRef, createContext, useMemo, useContext, useCallback } from 'react';
|
|
3
|
+
import require$$1 from 'react-dom';
|
|
4
|
+
import { create } from 'zustand';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Main SDK client for Pear Protocol Hyperliquid API integration
|
|
8
|
+
*/
|
|
9
|
+
class PearHyperliquidClient {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
12
|
+
this.httpClient = axios.create({
|
|
13
|
+
baseURL: this.baseUrl,
|
|
14
|
+
timeout: config.timeout || 30000,
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
...config.headers,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
// Add response interceptor for error handling
|
|
21
|
+
this.httpClient.interceptors.response.use((response) => response, (error) => {
|
|
22
|
+
var _a, _b, _c, _d, _e;
|
|
23
|
+
const apiError = {
|
|
24
|
+
statusCode: ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || 500,
|
|
25
|
+
message: ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) || error.message,
|
|
26
|
+
error: (_e = (_d = error.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.error,
|
|
27
|
+
};
|
|
28
|
+
return Promise.reject(apiError);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the configured base URL
|
|
33
|
+
*/
|
|
34
|
+
getBaseUrl() {
|
|
35
|
+
return this.baseUrl;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Update request headers
|
|
39
|
+
*/
|
|
40
|
+
setHeaders(headers) {
|
|
41
|
+
this.httpClient.defaults.headers = {
|
|
42
|
+
...this.httpClient.defaults.headers,
|
|
43
|
+
...headers,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set authorization header
|
|
48
|
+
*/
|
|
49
|
+
setAuthToken(token) {
|
|
50
|
+
this.setHeaders({ Authorization: `Bearer ${token}` });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Make a generic HTTP request
|
|
54
|
+
*/
|
|
55
|
+
async makeRequest(method, endpoint, data) {
|
|
56
|
+
const response = await this.httpClient.request({
|
|
57
|
+
method,
|
|
58
|
+
url: endpoint,
|
|
59
|
+
data,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
data: response.data,
|
|
63
|
+
status: response.status,
|
|
64
|
+
headers: response.headers,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sync trade history data from old database structure to new database format
|
|
69
|
+
* @param payload - Trade history data with user address
|
|
70
|
+
* @returns Promise with sync result
|
|
71
|
+
*/
|
|
72
|
+
async syncTradeHistory(payload) {
|
|
73
|
+
return this.makeRequest('POST', '/syncer/trade-histories', payload);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sync open positions data from old database structure to new database format
|
|
77
|
+
* @param payload - Open positions data with user address
|
|
78
|
+
* @returns Promise with sync result
|
|
79
|
+
*/
|
|
80
|
+
async syncOpenPositions(payload) {
|
|
81
|
+
return this.makeRequest('POST', '/syncer/open-positions', payload);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Sync open orders data from old database structure to new database format
|
|
85
|
+
* @param payload - Open orders data with user address
|
|
86
|
+
* @returns Promise with sync result
|
|
87
|
+
*/
|
|
88
|
+
async syncOpenOrders(payload) {
|
|
89
|
+
return this.makeRequest('POST', '/syncer/open-orders', payload);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Fetch historical candle data from HyperLiquid API
|
|
93
|
+
* @param coin - Token symbol (e.g., 'BTC', 'ETH')
|
|
94
|
+
* @param startTime - Start time in milliseconds
|
|
95
|
+
* @param endTime - End time in milliseconds
|
|
96
|
+
* @param interval - Candle interval
|
|
97
|
+
* @returns Promise with historical candle data
|
|
98
|
+
*/
|
|
99
|
+
async fetchHistoricalCandles(coin, startTime, endTime, interval) {
|
|
100
|
+
var _a, _b, _c, _d, _e;
|
|
101
|
+
const request = {
|
|
102
|
+
req: {
|
|
103
|
+
coin,
|
|
104
|
+
startTime,
|
|
105
|
+
endTime,
|
|
106
|
+
interval: interval
|
|
107
|
+
},
|
|
108
|
+
type: "candleSnapshot"
|
|
109
|
+
};
|
|
110
|
+
try {
|
|
111
|
+
const response = await axios.post('https://api.hyperliquid.xyz/info', request, {
|
|
112
|
+
headers: {
|
|
113
|
+
'Content-Type': 'application/json',
|
|
114
|
+
},
|
|
115
|
+
timeout: 30000,
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
data: response.data,
|
|
119
|
+
status: response.status,
|
|
120
|
+
headers: response.headers,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
const axiosError = error;
|
|
125
|
+
const apiError = {
|
|
126
|
+
statusCode: ((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) || 500,
|
|
127
|
+
message: ((_c = (_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) || axiosError.message,
|
|
128
|
+
error: (_e = (_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.error,
|
|
129
|
+
};
|
|
130
|
+
throw apiError;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Main Migration SDK Class - Simple request/response pattern
|
|
137
|
+
*/
|
|
138
|
+
class PearMigrationSDK {
|
|
139
|
+
constructor(client) {
|
|
140
|
+
this.isTradeHistorySyncRunning = false;
|
|
141
|
+
this.isOpenPositionsSyncRunning = false;
|
|
142
|
+
this.isOpenOrdersSyncRunning = false;
|
|
143
|
+
this.client = client;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Sync trade history data - can only run one at a time
|
|
147
|
+
* If called while already running, returns immediately without making request
|
|
148
|
+
*/
|
|
149
|
+
async syncTradeHistory(payload) {
|
|
150
|
+
// If sync is already running, return immediately
|
|
151
|
+
if (this.isTradeHistorySyncRunning) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
this.isTradeHistorySyncRunning = true;
|
|
156
|
+
const response = await this.client.syncTradeHistory(payload);
|
|
157
|
+
return response;
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
this.isTradeHistorySyncRunning = false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Sync open positions data - can only run one at a time
|
|
165
|
+
* If called while already running, returns immediately without making request
|
|
166
|
+
*/
|
|
167
|
+
async syncOpenPositions(payload) {
|
|
168
|
+
// If sync is already running, return immediately
|
|
169
|
+
if (this.isOpenPositionsSyncRunning) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
this.isOpenPositionsSyncRunning = true;
|
|
174
|
+
const response = await this.client.syncOpenPositions(payload);
|
|
175
|
+
return response;
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
this.isOpenPositionsSyncRunning = false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Sync open orders data - can only run one at a time
|
|
183
|
+
* If called while already running, returns immediately without making request
|
|
184
|
+
*/
|
|
185
|
+
async syncOpenOrders(payload) {
|
|
186
|
+
// If sync is already running, return immediately
|
|
187
|
+
if (this.isOpenOrdersSyncRunning) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
this.isOpenOrdersSyncRunning = true;
|
|
192
|
+
const response = await this.client.syncOpenOrders(payload);
|
|
193
|
+
return response;
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
this.isOpenOrdersSyncRunning = false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if any sync is currently running
|
|
201
|
+
*/
|
|
202
|
+
isSyncInProgress() {
|
|
203
|
+
return this.isTradeHistorySyncRunning || this.isOpenPositionsSyncRunning || this.isOpenOrdersSyncRunning;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if trade history sync is currently running
|
|
207
|
+
*/
|
|
208
|
+
isTradeHistorySyncInProgress() {
|
|
209
|
+
return this.isTradeHistorySyncRunning;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check if open positions sync is currently running
|
|
213
|
+
*/
|
|
214
|
+
isOpenPositionsSyncInProgress() {
|
|
215
|
+
return this.isOpenPositionsSyncRunning;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Check if open orders sync is currently running
|
|
219
|
+
*/
|
|
220
|
+
isOpenOrdersSyncInProgress() {
|
|
221
|
+
return this.isOpenOrdersSyncRunning;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get the underlying client instance
|
|
225
|
+
*/
|
|
226
|
+
getClient() {
|
|
227
|
+
return this.client;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Set authorization token on the client
|
|
231
|
+
*/
|
|
232
|
+
setAuthToken(token) {
|
|
233
|
+
this.client.setAuthToken(token);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Set custom headers on the client
|
|
237
|
+
*/
|
|
238
|
+
setHeaders(headers) {
|
|
239
|
+
this.client.setHeaders(headers);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Get base URL from client
|
|
243
|
+
*/
|
|
244
|
+
getBaseUrl() {
|
|
245
|
+
return this.client.getBaseUrl();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
250
|
+
|
|
251
|
+
function getDefaultExportFromCjs (x) {
|
|
252
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
var jsxRuntime = {exports: {}};
|
|
256
|
+
|
|
257
|
+
var reactJsxRuntime_production = {};
|
|
258
|
+
|
|
259
|
+
/**
|
|
2
260
|
* @license React
|
|
3
261
|
* react-jsx-runtime.production.js
|
|
4
262
|
*
|
|
@@ -6,7 +264,42 @@ var et=Object.defineProperty;var d=(t,e)=>et(t,"name",{value:e,configurable:!0})
|
|
|
6
264
|
*
|
|
7
265
|
* This source code is licensed under the MIT license found in the
|
|
8
266
|
* LICENSE file in the root directory of this source tree.
|
|
9
|
-
*/
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
var hasRequiredReactJsxRuntime_production;
|
|
270
|
+
|
|
271
|
+
function requireReactJsxRuntime_production () {
|
|
272
|
+
if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
|
|
273
|
+
hasRequiredReactJsxRuntime_production = 1;
|
|
274
|
+
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
|
|
275
|
+
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
276
|
+
function jsxProd(type, config, maybeKey) {
|
|
277
|
+
var key = null;
|
|
278
|
+
void 0 !== maybeKey && (key = "" + maybeKey);
|
|
279
|
+
void 0 !== config.key && (key = "" + config.key);
|
|
280
|
+
if ("key" in config) {
|
|
281
|
+
maybeKey = {};
|
|
282
|
+
for (var propName in config)
|
|
283
|
+
"key" !== propName && (maybeKey[propName] = config[propName]);
|
|
284
|
+
} else maybeKey = config;
|
|
285
|
+
config = maybeKey.ref;
|
|
286
|
+
return {
|
|
287
|
+
$$typeof: REACT_ELEMENT_TYPE,
|
|
288
|
+
type: type,
|
|
289
|
+
key: key,
|
|
290
|
+
ref: void 0 !== config ? config : null,
|
|
291
|
+
props: maybeKey
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
|
|
295
|
+
reactJsxRuntime_production.jsx = jsxProd;
|
|
296
|
+
reactJsxRuntime_production.jsxs = jsxProd;
|
|
297
|
+
return reactJsxRuntime_production;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
var reactJsxRuntime_development = {};
|
|
301
|
+
|
|
302
|
+
/**
|
|
10
303
|
* @license React
|
|
11
304
|
* react-jsx-runtime.development.js
|
|
12
305
|
*
|
|
@@ -14,9 +307,3247 @@ var et=Object.defineProperty;var d=(t,e)=>et(t,"name",{value:e,configurable:!0})
|
|
|
14
307
|
*
|
|
15
308
|
* This source code is licensed under the MIT license found in the
|
|
16
309
|
* LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<%s key={someKey} {...props} />`,R,F,ae,F),$[F+R]=!0)}if(F=null,C!==void 0&&(n(C),F=""+C),s(p)&&(n(p.key),F=""+p.key),"key"in p){C={};for(var Ne in p)Ne!=="key"&&(C[Ne]=p[Ne])}else C=p;return F&&c(C,typeof v=="function"?v.displayName||v.name||"Unknown":v),i(v,F,G,ee,o(),C,Ce,Ae)}d(u,"jsxDEVImpl");function h(v){typeof v=="object"&&v!==null&&v.$$typeof===f&&v._store&&(v._store.validated=1)}d(h,"validateChildKeys");var g=ve,f=Symbol.for("react.transitional.element"),S=Symbol.for("react.portal"),A=Symbol.for("react.fragment"),E=Symbol.for("react.strict_mode"),m=Symbol.for("react.profiler"),k=Symbol.for("react.consumer"),w=Symbol.for("react.context"),O=Symbol.for("react.forward_ref"),I=Symbol.for("react.suspense"),j=Symbol.for("react.suspense_list"),N=Symbol.for("react.memo"),U=Symbol.for("react.lazy"),J=Symbol.for("react.activity"),T=Symbol.for("react.client.reference"),y=g.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,b=Object.prototype.hasOwnProperty,_=Array.isArray,P=console.createTask?console.createTask:function(){return null};g={react_stack_bottom_frame:d(function(v){return v()},"react_stack_bottom_frame")};var M,D={},z=g.react_stack_bottom_frame.bind(g,r)(),Q=P(a(r)),$={};le.Fragment=A,le.jsx=function(v,p,C,R,ee){var G=1e4>y.recentlyCreatedOwnerStacks++;return u(v,p,C,!1,R,ee,G?Error("react-stack-top-frame"):z,G?P(a(v)):Q)},le.jsxs=function(v,p,C,R,ee){var G=1e4>y.recentlyCreatedOwnerStacks++;return u(v,p,C,!0,R,ee,G?Error("react-stack-top-frame"):z,G?P(a(v)):Q)}})()),le}d(it,"requireReactJsxRuntime_development"),process.env.NODE_ENV==="production"?Re.exports=st():Re.exports=it();var ct=Re.exports,he={},ie={},x={};(function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.isEventSourceSupported=t.isReactNative=t.ReadyState=t.DEFAULT_HEARTBEAT=t.UNPARSABLE_JSON_OBJECT=t.DEFAULT_RECONNECT_INTERVAL_MS=t.DEFAULT_RECONNECT_LIMIT=t.SOCKET_IO_PING_CODE=t.SOCKET_IO_PATH=t.SOCKET_IO_PING_INTERVAL=t.DEFAULT_EVENT_SOURCE_OPTIONS=t.EMPTY_EVENT_HANDLERS=t.DEFAULT_OPTIONS=void 0;var e=1,n=1e3*e;t.DEFAULT_OPTIONS={},t.EMPTY_EVENT_HANDLERS={},t.DEFAULT_EVENT_SOURCE_OPTIONS={withCredentials:!1,events:t.EMPTY_EVENT_HANDLERS},t.SOCKET_IO_PING_INTERVAL=25*n,t.SOCKET_IO_PATH="/socket.io/?EIO=3&transport=websocket",t.SOCKET_IO_PING_CODE="2",t.DEFAULT_RECONNECT_LIMIT=20,t.DEFAULT_RECONNECT_INTERVAL_MS=5e3,t.UNPARSABLE_JSON_OBJECT={},t.DEFAULT_HEARTBEAT={message:"ping",timeout:6e4,interval:25e3};var a;(function(r){r[r.UNINSTANTIATED=-1]="UNINSTANTIATED",r[r.CONNECTING=0]="CONNECTING",r[r.OPEN=1]="OPEN",r[r.CLOSING=2]="CLOSING",r[r.CLOSED=3]="CLOSED"})(a||(t.ReadyState=a={}));var o=d(function(){try{return"EventSource"in globalThis}catch{return!1}},"eventSourceSupported");t.isReactNative=typeof navigator<"u"&&navigator.product==="ReactNative",t.isEventSourceSupported=!t.isReactNative&&o()})(x);var ge={},Se={};(function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.resetWebSockets=t.sharedWebSockets=void 0,t.sharedWebSockets={};var e=d(function(n){if(n&&t.sharedWebSockets.hasOwnProperty(n))delete t.sharedWebSockets[n];else for(var a in t.sharedWebSockets)t.sharedWebSockets.hasOwnProperty(a)&&delete t.sharedWebSockets[a]},"resetWebSockets");t.resetWebSockets=e})(Se);var ye={},Y={};Object.defineProperty(Y,"__esModule",{value:!0}),Y.setUpSocketIOPing=Y.appendQueryParams=Y.parseSocketIOUrl=void 0;var be=x,ut=d(function(t){if(t){var e=/^https|wss/.test(t),n=t.replace(/^(https?|wss?)(:\/\/)?/,""),a=n.replace(/\/$/,""),o=e?"wss":"ws";return"".concat(o,"://").concat(a).concat(be.SOCKET_IO_PATH)}else if(t===""){var e=/^https/.test(window.location.protocol),o=e?"wss":"ws",r=window.location.port?":".concat(window.location.port):"";return"".concat(o,"://").concat(window.location.hostname).concat(r).concat(be.SOCKET_IO_PATH)}return t},"parseSocketIOUrl");Y.parseSocketIOUrl=ut;var lt=d(function(t,e){e===void 0&&(e={});var n=/\?([\w]+=[\w]+)/,a=n.test(t),o="".concat(Object.entries(e).reduce(function(r,s){var c=s[0],l=s[1];return r+"".concat(c,"=").concat(l,"&")},"").slice(0,-1));return"".concat(t).concat(a?"&":"?").concat(o)},"appendQueryParams");Y.appendQueryParams=lt;var dt=d(function(t,e){e===void 0&&(e=be.SOCKET_IO_PING_INTERVAL);var n=d(function(){return t(be.SOCKET_IO_PING_CODE)},"ping");return window.setInterval(n,e)},"setUpSocketIOPing");Y.setUpSocketIOPing=dt;var me={};Object.defineProperty(me,"__esModule",{value:!0}),me.heartbeat=vt;var Le=x;function ft(t){return Array.isArray(t)?t.reduce(function(e,n){return e.current>n.current?e:n}).current:t.current}d(ft,"getLastMessageTime");function vt(t,e,n){var a=n||{},o=a.interval,r=o===void 0?Le.DEFAULT_HEARTBEAT.interval:o,s=a.timeout,c=s===void 0?Le.DEFAULT_HEARTBEAT.timeout:s,l=a.message,i=l===void 0?Le.DEFAULT_HEARTBEAT.message:l,u=Math.max(100,r/10),h=Date.now(),g=setInterval(function(){var f=Date.now(),S=ft(e);if(S+c<=f)console.warn("Heartbeat timed out, closing connection, last message received ".concat(f-S,"ms ago, last ping sent ").concat(f-h,"ms ago")),t.close();else if(S+r<=f&&h+r<=f)try{typeof i=="function"?t.send(i()):t.send(i),h=f}catch(A){console.error("Heartbeat failed, closing connection",A instanceof Error?A.message:A),t.close()}},u);return t.addEventListener("close",function(){clearInterval(g)}),function(){}}d(vt,"heartbeat");var ce={},Te={};(function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.resetSubscribers=t.removeSubscriber=t.addSubscriber=t.hasSubscribers=t.getSubscribers=void 0;var e={},n=[],a=d(function(l){return(0,t.hasSubscribers)(l)?Array.from(e[l]):n},"getSubscribers");t.getSubscribers=a;var o=d(function(l){var i;return((i=e[l])===null||i===void 0?void 0:i.size)>0},"hasSubscribers");t.hasSubscribers=o;var r=d(function(l,i){e[l]=e[l]||new Set,e[l].add(i)},"addSubscriber");t.addSubscriber=r;var s=d(function(l,i){e[l].delete(i)},"removeSubscriber");t.removeSubscriber=s;var c=d(function(l){if(l&&e.hasOwnProperty(l))delete e[l];else for(var i in e)e.hasOwnProperty(i)&&delete e[i]},"resetSubscribers");t.resetSubscribers=c})(Te),Object.defineProperty(ce,"__esModule",{value:!0}),ce.assertIsWebSocket=St,ce.resetGlobalState=yt;var ht=Se,gt=Te;function St(t,e){if(!e&&!(t instanceof WebSocket))throw new Error("")}d(St,"assertIsWebSocket");function yt(t){(0,gt.resetSubscribers)(t),(0,ht.resetWebSockets)(t)}d(yt,"resetGlobalState");var Ee=L&&L.__assign||function(){return Ee=Object.assign||function(t){for(var e,n=1,a=arguments.length;n<a;n++){e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},Ee.apply(this,arguments)};Object.defineProperty(ye,"__esModule",{value:!0}),ye.attachListeners=void 0;var bt=Y,mt=me,B=x,Tt=ce,Et=d(function(t,e,n,a){t.onmessage=function(o){var r;e.current.onMessage&&e.current.onMessage(o),typeof a?.current=="number"&&(a.current=Date.now()),!(typeof e.current.filter=="function"&&e.current.filter(o)!==!0)&&(e.current.heartbeat&&typeof e.current.heartbeat!="boolean"&&((r=e.current.heartbeat)===null||r===void 0?void 0:r.returnMessage)===o.data||n(o))}},"bindMessageHandler$1"),_t=d(function(t,e,n,a,o){t.onopen=function(r){if(e.current.onOpen&&e.current.onOpen(r),a.current=0,n(B.ReadyState.OPEN),e.current.heartbeat&&t instanceof WebSocket){var s=typeof e.current.heartbeat=="boolean"?void 0:e.current.heartbeat;o.current=Date.now(),(0,mt.heartbeat)(t,o,s)}}},"bindOpenHandler$1"),Ot=d(function(t,e,n,a,o){if(B.isEventSourceSupported&&t instanceof EventSource)return function(){};(0,Tt.assertIsWebSocket)(t,e.current.skipAssert);var r;return t.onclose=function(s){var c;if(e.current.onClose&&e.current.onClose(s),n(B.ReadyState.CLOSED),e.current.shouldReconnect&&e.current.shouldReconnect(s)){var l=(c=e.current.reconnectAttempts)!==null&&c!==void 0?c:B.DEFAULT_RECONNECT_LIMIT;if(o.current<l){var i=typeof e.current.reconnectInterval=="function"?e.current.reconnectInterval(o.current):e.current.reconnectInterval;r=window.setTimeout(function(){o.current++,a()},i??B.DEFAULT_RECONNECT_INTERVAL_MS)}else e.current.onReconnectStop&&e.current.onReconnectStop(l),console.warn("Max reconnect attempts of ".concat(l," exceeded"))}},function(){return r&&window.clearTimeout(r)}},"bindCloseHandler$1"),pt=d(function(t,e,n,a,o){var r;return t.onerror=function(s){var c;if(e.current.onError&&e.current.onError(s),B.isEventSourceSupported&&t instanceof EventSource&&(e.current.onClose&&e.current.onClose(Ee(Ee({},s),{code:1006,reason:"An error occurred with the EventSource: ".concat(s),wasClean:!1})),n(B.ReadyState.CLOSED),t.close()),e.current.retryOnError)if(o.current<((c=e.current.reconnectAttempts)!==null&&c!==void 0?c:B.DEFAULT_RECONNECT_LIMIT)){var l=typeof e.current.reconnectInterval=="function"?e.current.reconnectInterval(o.current):e.current.reconnectInterval;r=window.setTimeout(function(){o.current++,a()},l??B.DEFAULT_RECONNECT_INTERVAL_MS)}else e.current.onReconnectStop&&e.current.onReconnectStop(e.current.reconnectAttempts),console.warn("Max reconnect attempts of ".concat(e.current.reconnectAttempts," exceeded"))},function(){return r&&window.clearTimeout(r)}},"bindErrorHandler$1"),wt=d(function(t,e,n,a,o,r,s){var c=e.setLastMessage,l=e.setReadyState,i,u,h;return n.current.fromSocketIO&&(i=(0,bt.setUpSocketIOPing)(s)),Et(t,n,c,r),_t(t,n,l,o,r),u=Ot(t,n,l,a,o),h=pt(t,n,l,a,o),function(){l(B.ReadyState.CLOSING),u(),h(),t.close(),i&&clearInterval(i)}},"attachListeners");ye.attachListeners=wt;var _e={},Oe=L&&L.__assign||function(){return Oe=Object.assign||function(t){for(var e,n=1,a=arguments.length;n<a;n++){e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},Oe.apply(this,arguments)};Object.defineProperty(_e,"__esModule",{value:!0}),_e.attachSharedListeners=void 0;var Pt=Se,oe=x,de=Te,kt=Y,Ct=me,At=d(function(t,e,n){t.onmessage=function(a){(0,de.getSubscribers)(e).forEach(function(o){var r;o.optionsRef.current.onMessage&&o.optionsRef.current.onMessage(a),typeof((r=o?.lastMessageTime)===null||r===void 0?void 0:r.current)=="number"&&(o.lastMessageTime.current=Date.now()),!(typeof o.optionsRef.current.filter=="function"&&o.optionsRef.current.filter(a)!==!0)&&(n&&typeof n!="boolean"&&n?.returnMessage===a.data||o.setLastMessage(a))})}},"bindMessageHandler"),Nt=d(function(t,e,n){t.onopen=function(a){var o=(0,de.getSubscribers)(e);o.forEach(function(r){r.reconnectCount.current=0,r.optionsRef.current.onOpen&&r.optionsRef.current.onOpen(a),r.setReadyState(oe.ReadyState.OPEN),n&&t instanceof WebSocket&&(r.lastMessageTime.current=Date.now())}),n&&t instanceof WebSocket&&(0,Ct.heartbeat)(t,o.map(function(r){return r.lastMessageTime}),typeof n=="boolean"?void 0:n)}},"bindOpenHandler"),Mt=d(function(t,e){t instanceof WebSocket&&(t.onclose=function(n){(0,de.getSubscribers)(e).forEach(function(a){a.optionsRef.current.onClose&&a.optionsRef.current.onClose(n),a.setReadyState(oe.ReadyState.CLOSED)}),delete Pt.sharedWebSockets[e],(0,de.getSubscribers)(e).forEach(function(a){var o;if(a.optionsRef.current.shouldReconnect&&a.optionsRef.current.shouldReconnect(n)){var r=(o=a.optionsRef.current.reconnectAttempts)!==null&&o!==void 0?o:oe.DEFAULT_RECONNECT_LIMIT;if(a.reconnectCount.current<r){var s=typeof a.optionsRef.current.reconnectInterval=="function"?a.optionsRef.current.reconnectInterval(a.reconnectCount.current):a.optionsRef.current.reconnectInterval;setTimeout(function(){a.reconnectCount.current++,a.reconnect.current()},s??oe.DEFAULT_RECONNECT_INTERVAL_MS)}else a.optionsRef.current.onReconnectStop&&a.optionsRef.current.onReconnectStop(a.optionsRef.current.reconnectAttempts),console.warn("Max reconnect attempts of ".concat(r," exceeded"))}})})},"bindCloseHandler"),Rt=d(function(t,e){t.onerror=function(n){(0,de.getSubscribers)(e).forEach(function(a){a.optionsRef.current.onError&&a.optionsRef.current.onError(n),oe.isEventSourceSupported&&t instanceof EventSource&&(a.optionsRef.current.onClose&&a.optionsRef.current.onClose(Oe(Oe({},n),{code:1006,reason:"An error occurred with the EventSource: ".concat(n),wasClean:!1})),a.setReadyState(oe.ReadyState.CLOSED))}),oe.isEventSourceSupported&&t instanceof EventSource&&t.close()}},"bindErrorHandler"),Lt=d(function(t,e,n,a){var o;return n.current.fromSocketIO&&(o=(0,kt.setUpSocketIOPing)(a)),At(t,e,n.current.heartbeat),Mt(t,e),Nt(t,e,n.current.heartbeat),Rt(t,e),function(){o&&clearInterval(o)}},"attachSharedListeners");_e.attachSharedListeners=Lt,Object.defineProperty(ge,"__esModule",{value:!0}),ge.createOrJoinSocket=void 0;var te=Se,fe=x,It=ye,Dt=_e,Ie=Te,Wt=d(function(t,e,n,a,o){return function(){if((0,Ie.removeSubscriber)(t,e),!(0,Ie.hasSubscribers)(t)){try{var r=te.sharedWebSockets[t];r instanceof WebSocket&&(r.onclose=function(s){n.current.onClose&&n.current.onClose(s),a(fe.ReadyState.CLOSED)}),r.close()}catch{}o&&o(),delete te.sharedWebSockets[t]}}},"cleanSubscribers"),Ut=d(function(t,e,n,a,o,r,s,c,l){if(!fe.isEventSourceSupported&&a.current.eventSourceOptions)throw fe.isReactNative?new Error("EventSource is not supported in ReactNative"):new Error("EventSource is not supported");if(a.current.share){var i=null;te.sharedWebSockets[e]===void 0?(te.sharedWebSockets[e]=a.current.eventSourceOptions?new EventSource(e,a.current.eventSourceOptions):new WebSocket(e,a.current.protocols),t.current=te.sharedWebSockets[e],n(fe.ReadyState.CONNECTING),i=(0,Dt.attachSharedListeners)(te.sharedWebSockets[e],e,a,l)):(t.current=te.sharedWebSockets[e],n(te.sharedWebSockets[e].readyState));var u={setLastMessage:o,setReadyState:n,optionsRef:a,reconnectCount:s,lastMessageTime:c,reconnect:r};return(0,Ie.addSubscriber)(e,u),Wt(e,u,a,n,i)}else{if(t.current=a.current.eventSourceOptions?new EventSource(e,a.current.eventSourceOptions):new WebSocket(e,a.current.protocols),n(fe.ReadyState.CONNECTING),!t.current)throw new Error("WebSocket failed to be created");return(0,It.attachListeners)(t.current,{setLastMessage:o,setReadyState:n},a,r.current,s,c,l)}},"createOrJoinSocket");ge.createOrJoinSocket=Ut;var $e={};(function(t){var e=L&&L.__awaiter||function(l,i,u,h){function g(f){return f instanceof u?f:new u(function(S){S(f)})}return d(g,"adopt"),new(u||(u=Promise))(function(f,S){function A(k){try{m(h.next(k))}catch(w){S(w)}}d(A,"fulfilled");function E(k){try{m(h.throw(k))}catch(w){S(w)}}d(E,"rejected");function m(k){k.done?f(k.value):g(k.value).then(A,E)}d(m,"step"),m((h=h.apply(l,i||[])).next())})},n=L&&L.__generator||function(l,i){var u={label:0,sent:d(function(){if(f[0]&1)throw f[1];return f[1]},"sent"),trys:[],ops:[]},h,g,f,S=Object.create((typeof Iterator=="function"?Iterator:Object).prototype);return S.next=A(0),S.throw=A(1),S.return=A(2),typeof Symbol=="function"&&(S[Symbol.iterator]=function(){return this}),S;function A(m){return function(k){return E([m,k])}}function E(m){if(h)throw new TypeError("Generator is already executing.");for(;S&&(S=0,m[0]&&(u=0)),u;)try{if(h=1,g&&(f=m[0]&2?g.return:m[0]?g.throw||((f=g.return)&&f.call(g),0):g.next)&&!(f=f.call(g,m[1])).done)return f;switch(g=0,f&&(m=[m[0]&2,f.value]),m[0]){case 0:case 1:f=m;break;case 4:return u.label++,{value:m[1],done:!1};case 5:u.label++,g=m[1],m=[0];continue;case 7:m=u.ops.pop(),u.trys.pop();continue;default:if(f=u.trys,!(f=f.length>0&&f[f.length-1])&&(m[0]===6||m[0]===2)){u=0;continue}if(m[0]===3&&(!f||m[1]>f[0]&&m[1]<f[3])){u.label=m[1];break}if(m[0]===6&&u.label<f[1]){u.label=f[1],f=m;break}if(f&&u.label<f[2]){u.label=f[2],u.ops.push(m);break}f[2]&&u.ops.pop(),u.trys.pop();continue}m=i.call(l,u)}catch(k){m=[6,k],g=0}finally{h=f=0}if(m[0]&5)throw m[1];return{value:m[0]?m[1]:void 0,done:!0}}},a=L&&L.__spreadArray||function(l,i,u){if(u||arguments.length===2)for(var h=0,g=i.length,f;h<g;h++)(f||!(h in i))&&(f||(f=Array.prototype.slice.call(i,0,h)),f[h]=i[h]);return l.concat(f||Array.prototype.slice.call(i))};Object.defineProperty(t,"__esModule",{value:!0}),t.getUrl=void 0;var o=Y,r=x,s=d(function(l){return new Promise(function(i){return window.setTimeout(i,l)})},"waitFor"),c=d(function(l,i){for(var u=[],h=2;h<arguments.length;h++)u[h-2]=arguments[h];return e(void 0,a([l,i],u,!0),void 0,function(g,f,S){var A,E,m,k,w,O,I,j;return S===void 0&&(S=0),n(this,function(N){switch(N.label){case 0:if(typeof g!="function")return[3,10];N.label=1;case 1:return N.trys.push([1,3,,9]),[4,g()];case 2:return A=N.sent(),[3,9];case 3:return N.sent(),f.current.retryOnError?(E=(O=f.current.reconnectAttempts)!==null&&O!==void 0?O:r.DEFAULT_RECONNECT_LIMIT,S<E?(m=typeof f.current.reconnectInterval=="function"?f.current.reconnectInterval(S):f.current.reconnectInterval,[4,s(m??r.DEFAULT_RECONNECT_INTERVAL_MS)]):[3,5]):[3,7];case 4:return N.sent(),[2,(0,t.getUrl)(g,f,S+1)];case 5:return(j=(I=f.current).onReconnectStop)===null||j===void 0||j.call(I,S),[2,null];case 6:return[3,8];case 7:return[2,null];case 8:return[3,9];case 9:return[3,11];case 10:A=g,N.label=11;case 11:return k=f.current.fromSocketIO?(0,o.parseSocketIOUrl)(A):A,w=f.current.queryParams?(0,o.appendQueryParams)(k,f.current.queryParams):k,[2,w]}})})},"getUrl");t.getUrl=c})($e);var ze={};(function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.websocketWrapper=void 0;var e=d(function(n,a){return new Proxy(n,{get:d(function(o,r){var s=o[r];return r==="reconnect"?a:typeof s=="function"?(console.error("Calling methods directly on the websocket is not supported at this moment. You must use the methods returned by useWebSocket."),function(){}):s},"get"),set:d(function(o,r,s){return/^on/.test(r)?(console.warn("The websocket's event handlers should be defined through the options object passed into useWebSocket."),!1):(o[r]=s,!0)},"set")})},"websocketWrapper");t.websocketWrapper=e,t.default=t.websocketWrapper})(ze);var ne=L&&L.__assign||function(){return ne=Object.assign||function(t){for(var e,n=1,a=arguments.length;n<a;n++){e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},ne.apply(this,arguments)},jt=L&&L.__awaiter||function(t,e,n,a){function o(r){return r instanceof n?r:new n(function(s){s(r)})}return d(o,"adopt"),new(n||(n=Promise))(function(r,s){function c(u){try{i(a.next(u))}catch(h){s(h)}}d(c,"fulfilled");function l(u){try{i(a.throw(u))}catch(h){s(h)}}d(l,"rejected");function i(u){u.done?r(u.value):o(u.value).then(c,l)}d(i,"step"),i((a=a.apply(t,e||[])).next())})},Ft=L&&L.__generator||function(t,e){var n={label:0,sent:d(function(){if(r[0]&1)throw r[1];return r[1]},"sent"),trys:[],ops:[]},a,o,r,s=Object.create((typeof Iterator=="function"?Iterator:Object).prototype);return s.next=c(0),s.throw=c(1),s.return=c(2),typeof Symbol=="function"&&(s[Symbol.iterator]=function(){return this}),s;function c(i){return function(u){return l([i,u])}}function l(i){if(a)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(n=0)),n;)try{if(a=1,o&&(r=i[0]&2?o.return:i[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,i[1])).done)return r;switch(o=0,r&&(i=[i[0]&2,r.value]),i[0]){case 0:case 1:r=i;break;case 4:return n.label++,{value:i[1],done:!1};case 5:n.label++,o=i[1],i=[0];continue;case 7:i=n.ops.pop(),n.trys.pop();continue;default:if(r=n.trys,!(r=r.length>0&&r[r.length-1])&&(i[0]===6||i[0]===2)){n=0;continue}if(i[0]===3&&(!r||i[1]>r[0]&&i[1]<r[3])){n.label=i[1];break}if(i[0]===6&&n.label<r[1]){n.label=r[1],r=i;break}if(r&&n.label<r[2]){n.label=r[2],n.ops.push(i);break}r[2]&&n.ops.pop(),n.trys.pop();continue}i=e.call(t,n)}catch(u){i=[6,u],o=0}finally{a=r=0}if(i[0]&5)throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}},Ht=L&&L.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(ie,"__esModule",{value:!0}),ie.useWebSocket=void 0;var H=ve,De=ot,K=x,$t=ge,zt=$e,Vt=Ht(ze),Ve=ce,qt=d(function(t,e,n){e===void 0&&(e=K.DEFAULT_OPTIONS),n===void 0&&(n=!0);var a=(0,H.useState)(null),o=a[0],r=a[1],s=(0,H.useState)({}),c=s[0],l=s[1],i=(0,H.useMemo)(function(){if(!e.disableJson&&o)try{return JSON.parse(o.data)}catch{return K.UNPARSABLE_JSON_OBJECT}return null},[o,e.disableJson]),u=(0,H.useRef)(null),h=(0,H.useRef)(null),g=(0,H.useRef)(function(){}),f=(0,H.useRef)(0),S=(0,H.useRef)(Date.now()),A=(0,H.useRef)([]),E=(0,H.useRef)(null),m=(0,H.useRef)(e);m.current=e;var k=u.current&&c[u.current]!==void 0?c[u.current]:t!==null&&n===!0?K.ReadyState.CONNECTING:K.ReadyState.UNINSTANTIATED,w=e.queryParams?JSON.stringify(e.queryParams):null,O=(0,H.useCallback)(function(N,U){var J;if(U===void 0&&(U=!0),K.isEventSourceSupported&&h.current instanceof EventSource){console.warn("Unable to send a message from an eventSource");return}((J=h.current)===null||J===void 0?void 0:J.readyState)===K.ReadyState.OPEN?((0,Ve.assertIsWebSocket)(h.current,m.current.skipAssert),h.current.send(N)):U&&A.current.push(N)},[]),I=(0,H.useCallback)(function(N,U){U===void 0&&(U=!0),O(JSON.stringify(N),U)},[O]),j=(0,H.useCallback)(function(){return m.current.share!==!0||K.isEventSourceSupported&&h.current instanceof EventSource?h.current:(E.current===null&&h.current&&((0,Ve.assertIsWebSocket)(h.current,m.current.skipAssert),E.current=(0,Vt.default)(h.current,g)),E.current)},[]);return(0,H.useEffect)(function(){if(t!==null&&n===!0){var N,U=!1,J=!0,T=d(function(){return jt(void 0,void 0,void 0,function(){var y,b,_;return Ft(this,function(P){switch(P.label){case 0:return y=u,[4,(0,zt.getUrl)(t,m)];case 1:return y.current=P.sent(),u.current===null?(console.error("Failed to get a valid URL. WebSocket connection aborted."),u.current="ABORTED",(0,De.flushSync)(function(){return l(function(M){return ne(ne({},M),{ABORTED:K.ReadyState.CLOSED})})}),[2]):(b=d(function(M){U||(0,De.flushSync)(function(){return r(M)})},"protectedSetLastMessage"),_=d(function(M){U||(0,De.flushSync)(function(){return l(function(D){var z;return ne(ne({},D),u.current&&(z={},z[u.current]=M,z))})})},"protectedSetReadyState"),J&&(N=(0,$t.createOrJoinSocket)(h,u.current,_,m,b,g,f,S,O)),[2])}})})},"start_1");return g.current=function(){U||(E.current&&(E.current=null),N?.(),T())},T(),function(){U=!0,J=!1,E.current&&(E.current=null),N?.(),r(null)}}else(t===null||n===!1)&&(f.current=0,l(function(y){var b;return ne(ne({},y),u.current&&(b={},b[u.current]=K.ReadyState.CLOSED,b))}))},[t,n,w,O]),(0,H.useEffect)(function(){k===K.ReadyState.OPEN&&A.current.splice(0).forEach(function(N){O(N)})},[k]),{sendMessage:O,sendJsonMessage:I,lastMessage:o,lastJsonMessage:i,readyState:k,getWebSocket:j}},"useWebSocket$1");ie.useWebSocket=qt;var pe={},we=L&&L.__assign||function(){return we=Object.assign||function(t){for(var e,n=1,a=arguments.length;n<a;n++){e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},we.apply(this,arguments)};Object.defineProperty(pe,"__esModule",{value:!0}),pe.useSocketIO=void 0;var qe=ve,xt=ie,Jt=x,We={type:"empty",payload:null},Gt=d(function(t){if(!t||!t.data)return We;var e=t.data.match(/\[.*]/);if(!e)return We;var n=JSON.parse(e);return!Array.isArray(n)||!n[1]?We:{type:n[0],payload:n[1]}},"getSocketData"),Yt=d(function(t,e,n){e===void 0&&(e=Jt.DEFAULT_OPTIONS),n===void 0&&(n=!0);var a=(0,qe.useMemo)(function(){return we(we({},e),{fromSocketIO:!0})},[]),o=(0,xt.useWebSocket)(t,a,n),r=o.sendMessage,s=o.sendJsonMessage,c=o.lastMessage,l=o.readyState,i=o.getWebSocket,u=(0,qe.useMemo)(function(){return Gt(c)},[c]);return{sendMessage:r,sendJsonMessage:s,lastMessage:u,lastJsonMessage:u,readyState:l,getWebSocket:i}},"useSocketIO");pe.useSocketIO=Yt;var Pe={},ke=L&&L.__assign||function(){return ke=Object.assign||function(t){for(var e,n=1,a=arguments.length;n<a;n++){e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},ke.apply(this,arguments)},Bt=L&&L.__rest||function(t,e){var n={};for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&e.indexOf(a)<0&&(n[a]=t[a]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,a=Object.getOwnPropertySymbols(t);o<a.length;o++)e.indexOf(a[o])<0&&Object.prototype.propertyIsEnumerable.call(t,a[o])&&(n[a[o]]=t[a[o]]);return n};Object.defineProperty(Pe,"__esModule",{value:!0}),Pe.useEventSource=void 0;var xe=ve,Kt=ie,Je=x,Xt=d(function(t,e,n){e===void 0&&(e=Je.DEFAULT_EVENT_SOURCE_OPTIONS);var a=e.withCredentials,o=e.events,r=Bt(e,["withCredentials","events"]);n===void 0&&(n=!0);var s=ke(ke({},r),{eventSourceOptions:{withCredentials:a}}),c=(0,xe.useRef)(Je.EMPTY_EVENT_HANDLERS);o&&(c.current=o);var l=(0,Kt.useWebSocket)(t,s,n),i=l.lastMessage,u=l.readyState,h=l.getWebSocket;return(0,xe.useEffect)(function(){i?.type&&Object.entries(c.current).forEach(function(g){var f=g[0],S=g[1];f===i.type&&S(i)})},[i]),{lastEvent:i,readyState:u,getEventSource:h}},"useEventSource");Pe.useEventSource=Xt,(function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.resetGlobalState=t.useEventSource=t.ReadyState=t.useSocketIO=t.default=void 0;var e=ie;Object.defineProperty(t,"default",{enumerable:!0,get:d(function(){return e.useWebSocket},"get")});var n=pe;Object.defineProperty(t,"useSocketIO",{enumerable:!0,get:d(function(){return n.useSocketIO},"get")});var a=x;Object.defineProperty(t,"ReadyState",{enumerable:!0,get:d(function(){return a.ReadyState},"get")});var o=Pe;Object.defineProperty(t,"useEventSource",{enumerable:!0,get:d(function(){return o.useEventSource},"get")});var r=ce;Object.defineProperty(t,"resetGlobalState",{enumerable:!0,get:d(function(){return r.resetGlobalState},"get")})})(he);var Ge=at(he);const Ye=d(({wsUrl:t,address:e})=>{const[n,a]=V({tradeHistories:null,openPositions:null,openOrders:null,accountSummary:null}),[o,r]=V(null),[s,c]=V(null),{readyState:l,sendMessage:i}=Ge(t,{shouldReconnect:d(()=>!0,"shouldReconnect"),reconnectAttempts:5,reconnectInterval:3e3,onMessage:d(h=>{try{const g=JSON.parse(h.data);if(("success"in g||"error"in g)&&!("channel"in g)){g.error?r(g.error):r(null);return}if("channel"in g&&"data"in g){const f=g;if(f.data===null||f.data===void 0)return;switch(f.channel){case"trade-histories":Array.isArray(f.data)&&a(S=>({...S,tradeHistories:f.data}));break;case"open-positions":Array.isArray(f.data)&&a(S=>({...S,openPositions:f.data}));break;case"open-orders":Array.isArray(f.data)&&a(S=>({...S,openOrders:f.data}));break;case"account-summary":typeof f.data=="object"&&f.data!==null&&a(S=>({...S,accountSummary:f.data}));break}}}catch(g){r(`Failed to parse message: ${g instanceof Error?g.message:String(g)}`)}},"onMessage")}),u=l===he.ReadyState.OPEN;return se(()=>{u&&e&&e!==s?(s&&i(JSON.stringify({action:"unsubscribe",address:s})),i(JSON.stringify({action:"subscribe",address:e})),c(e),r(null)):u&&!e&&s&&(i(JSON.stringify({action:"unsubscribe",address:s})),c(null))},[u,e,s,i]),se(()=>{e!==s&&(a({tradeHistories:null,openPositions:null,openOrders:null,accountSummary:null}),r(null))},[e,s]),{data:n,connectionStatus:l,isConnected:u,lastError:o}},"useHyperliquidWebSocket"),Be=d(({address:t,tokens:e=[]})=>{const[n,a]=V(null),[o,r]=V(null),[s,c]=V(null),[l,i]=V(null),[u,h]=V(null),[g,f]=V([]),S=nt(null),{readyState:A,sendJsonMessage:E}=Ge("wss://api.hyperliquid.xyz/ws",{shouldReconnect:d(()=>!0,"shouldReconnect"),reconnectAttempts:5,reconnectInterval:3e3,onOpen:d(()=>{},"onOpen"),onClose:d(()=>{},"onClose"),onError:d(k=>console.error("[HyperLiquid WS] Connection error:",k),"onError"),onReconnectStop:d(()=>console.error("[HyperLiquid WS] Reconnection stopped after 5 attempts"),"onReconnectStop"),onMessage:d(k=>{try{const w=JSON.parse(k.data);if("success"in w||"error"in w){w.error?(console.error("[HyperLiquid WS] Subscription error:",w.error),i(w.error)):i(null);return}if("channel"in w&&"data"in w){const O=w;switch(O.channel){case"webData2":a(O.data);break;case"allMids":r(O.data);break;case"activeAssetData":const I=O.data;c(j=>({...j,[I.coin]:I}));break;default:console.warn(`[HyperLiquid WS] Unknown channel: ${O.channel}`)}}}catch(w){const O=`Failed to parse message: ${w instanceof Error?w.message:String(w)}`;console.error("[HyperLiquid WS] Parse error:",O,"Raw message:",k.data),i(O)}},"onMessage")}),m=A===he.ReadyState.OPEN;return se(()=>(m?S.current=setInterval(()=>{E({method:"ping"})},3e4):S.current&&(clearInterval(S.current),S.current=null),()=>{S.current&&(clearInterval(S.current),S.current=null)}),[m,E]),se(()=>{if(!m)return;const w=t||"0x0000000000000000000000000000000000000000";if(u===w)return;u&&E({method:"unsubscribe",subscription:{type:"webData2",user:u}});const O={method:"subscribe",subscription:{type:"webData2",user:w}},I={method:"subscribe",subscription:{type:"allMids"}};E(O),E(I),h(w),u&&u!==w&&a(null)},[m,t,u,E]),se(()=>{if(!m||!t)return;const k=e.filter(O=>O&&!g.includes(O)),w=g.filter(O=>!e.includes(O));w.forEach(O=>{E({method:"unsubscribe",subscription:{type:"activeAssetData",user:t,coin:O}})}),k.forEach(O=>{E({method:"subscribe",subscription:{type:"activeAssetData",user:t,coin:O}})}),(k.length>0||w.length>0)&&(f(e.filter(O=>O)),w.length>0&&c(O=>{if(!O)return O;const I={...O};return w.forEach(j=>{delete I[j]}),Object.keys(I).length>0?I:null}))},[m,t,e,g,E]),{webData2:n,allMids:o,activeAssetData:s,connectionStatus:A,isConnected:m,lastError:l}},"useHyperliquidNativeWebSocket"),Qt={longTokens:[{symbol:"HYPE",weight:25},{symbol:"BTC",weight:25}],shortTokens:[{symbol:"AVAX",weight:10},{symbol:"SEI",weight:10},{symbol:"ADA",weight:10},{symbol:"TRUMP",weight:10},{symbol:"SUI",weight:10}],openTokenSelector:!1,selectorConfig:null,openConflictModal:!1,conflicts:[],leverageMatched:!1},X=rt(void 0),Zt=d(({config:t,wsUrl:e="wss://hl-v2.pearprotocol.io/ws",children:n})=>{const a=W(()=>new Me(t),[t]),o=W(()=>new je(a),[a]),[r,s]=V(null),[c,l]=V(Qt),i=W(()=>{const I=c.longTokens.map(N=>N.symbol),j=c.shortTokens.map(N=>N.symbol);return[...new Set([...I,...j])]},[c.longTokens,c.shortTokens]),{data:u,connectionStatus:h,isConnected:g,lastError:f}=Ye({wsUrl:e,address:r}),{webData2:S,allMids:A,activeAssetData:E,connectionStatus:m,isConnected:k,lastError:w}=Be({address:r,tokens:i}),O=W(()=>({client:a,migrationSDK:o,address:r,setAddress:s,connectionStatus:h,isConnected:g,data:u,lastError:f,nativeConnectionStatus:m,nativeIsConnected:k,nativeLastError:w,webData2:S,allMids:A,activeAssetData:E,tokenSelection:c,setTokenSelection:l}),[a,o,r,h,g,u,f,m,k,w,S,A,E,c,l]);return ct.jsx(X.Provider,{value:O,children:n})},"PearHyperliquidProvider"),en=d(()=>{const t=Z(X);if(!t)throw new Error("usePearHyperliquidClient must be used within a PearHyperliquidProvider");return t.client},"usePearHyperliquidClient"),tn=d(()=>{const t=Z(X);if(!t)throw new Error("useMigrationSDK must be used within a PearHyperliquidProvider");return t.migrationSDK},"useMigrationSDK"),nn=d(()=>{const t=Z(X);if(!t)throw new Error("useAddress must be used within a PearHyperliquidProvider");return{address:t.address,setAddress:t.setAddress,clearAddress:d(()=>t.setAddress(null),"clearAddress"),isLoggedIn:!!t.address}},"useAddress");var re;(function(t){t.LONG="LONG",t.SHORT="SHORT"})(re||(re={}));class rn{static{d(this,"PositionProcessor")}constructor(e,n){this.webData2=e,this.allMids=n}execute(e){if(!e||e.length===0)return[];const n=this.getUserPositions(),a=this.calculatePlatformTotalsByAsset(e),o=new Map;(n||[]).forEach(s=>{var c;!((c=s.position)===null||c===void 0)&&c.coin&&o.set(s.position.coin,s)});const r=[];for(const s of e){const c=this.syncPositionWithAggregateData(s,o,a);r.push(c)}return r}getUserPositions(){var e,n;return((n=(e=this.webData2)===null||e===void 0?void 0:e.clearinghouseState)===null||n===void 0?void 0:n.assetPositions)||[]}getMarketPrice(e){var n;if(!(!((n=this.allMids)===null||n===void 0)&&n.mids))return 0;const a=this.allMids.mids[e];if(a)return Number(a);const o=this.extractBaseCurrency(e),r=this.allMids.mids[o];return r?Number(r):0}calculatePlatformTotalsByAsset(e){const n=new Map;for(const a of e){for(const o of a.longAssets||[]){const r=this.extractBaseCurrency(o.coin);n.has(r)||n.set(r,{totalSize:0,positions:[]});const s=n.get(r),c=Number(o.size||0);s.totalSize+=c,s.positions.push({positionId:a.positionId,asset:o,size:c})}for(const o of a.shortAssets||[]){const r=this.extractBaseCurrency(o.coin);n.has(r)||n.set(r,{totalSize:0,positions:[]});const s=n.get(r),c=Number(o.size||0);s.totalSize+=c,s.positions.push({positionId:a.positionId,asset:o,size:c})}}return n}extractBaseCurrency(e){return e.split("/")[0]||e}syncPositionWithAggregateData(e,n,a){const o=[];let r=!1,s=!0,c={total:0,closed:0},l={total:0,closed:0};for(const u of e.longAssets||[]){const h=this.extractBaseCurrency(u.coin),g=n.get(h),f=a.get(h),S=this.syncAssetWithAggregateData({...u,side:re.LONG},g,f?.totalSize||0);o.push(S),c.total++,S.actualSize===0&&c.closed++,S.isExternallyModified&&(r=!0),S.actualSize!==0&&(s=!1)}for(const u of e.shortAssets||[]){const h=this.extractBaseCurrency(u.coin),g=n.get(h),f=a.get(h),S=this.syncAssetWithAggregateData({...u,side:re.SHORT},g,f?.totalSize||0);o.push(S),l.total++,S.actualSize===0&&l.closed++,S.isExternallyModified&&(r=!0),S.actualSize!==0&&(s=!1)}const i=this.determineSyncStatus(r,s,c,l);return this.mapPositionToDtoWithSyncData(e,o,i)}determineSyncStatus(e,n,a,o){if(n)return"EXTERNALLY_CLOSED";const r=a.total>0&&a.closed===a.total,s=o.total>0&&o.closed===o.total;return r&&!s||!r&&s?"PAIR_BROKEN":e?"EXTERNALLY_MODIFIED":"SYNCED"}syncAssetWithAggregateData(e,n,a){const o=Number(e.size||0);if(!n||!n.position||!n.position.szi)return{asset:e,actualSize:0,isExternallyModified:!0,cumFunding:{allTime:0,sinceChange:0,sinceOpen:0},unrealizedPnl:0,liquidationPrice:0};const r=Math.abs(Number(n.position.szi||0)),s=Math.abs(r-a),c=a*.001,l=s>c,i=a>0?o/a:0,u=r*i,h=n.position.cumFunding,g={allTime:Number(h?.allTime||0),sinceChange:Number(h?.sinceChange||0)*i,sinceOpen:Number(h?.sinceOpen||0)*i},f=Number(n.position.unrealizedPnl||0)*i,S=Number(n.position.liquidationPx||0);return{asset:e,actualSize:u,isExternallyModified:l,cumFunding:g,unrealizedPnl:f,liquidationPrice:S}}mapPositionToDtoWithSyncData(e,n,a){var o,r;const s=((o=e.longAssets)===null||o===void 0?void 0:o.filter(g=>g))||[],c=((r=e.shortAssets)===null||r===void 0?void 0:r.filter(g=>g))||[],l=new Map;n.forEach(g=>{l.set(`${g.asset.coin}-${g.asset.side}`,g)});const i=this.calculateCurrentTotalPositionValue(n),h=this.calculateEntryTotalPositionValue(n)/e.leverage;return{syncStatus:a,positionId:e.positionId,address:e.address,leverage:e.leverage,stopLoss:e.stopLoss,takeProfit:e.takeProfit,entryRatio:this.calculateEntryRatio(n),markRatio:this.calculateMarkRatio(n),netFunding:this.calculateNetFundingFromSyncResults(n),positionValue:i,marginUsed:h,unrealizedPnl:this.calculateTotalUnrealizedPnlFromSyncResults(n),lastSyncAt:new Date().toISOString(),longAssets:s.map(g=>this.mapAssetToDetailDto(g,l.get(`${g.coin}-LONG`))),shortAssets:c.map(g=>this.mapAssetToDetailDto(g,l.get(`${g.coin}-SHORT`))),createdAt:e.createdAt,updatedAt:e.updatedAt}}mapAssetToDetailDto(e,n){const a=this.getMarketPrice(e.coin),o=n?.actualSize||Number(e.size||0),r=o*a,s=Number(e.size||0)*Number(e.entryPrice||0);return{coin:e.coin,entryPrice:Number(e.entryPrice||0),platformSize:Number(e.size||0),actualSize:o,isExternallyModified:n?.isExternallyModified||!1,cumFunding:n?.cumFunding||{allTime:0,sinceChange:0,sinceOpen:0},marginUsed:s,positionValue:r,unrealizedPnl:n?.unrealizedPnl||0,liquidationPrice:n?.liquidationPrice||0}}calculateEntryRatio(e){var n,a;const o=e.filter(l=>l.asset.side===re.LONG),r=e.filter(l=>l.asset.side===re.SHORT);if(o.length===0||r.length===0)return 0;const s=!((n=o[0])===null||n===void 0)&&n.asset.entryPrice?Number(o[0].asset.entryPrice):0,c=!((a=r[0])===null||a===void 0)&&a.asset.entryPrice?Number(r[0].asset.entryPrice):0;return c>0?s/c:0}calculateMarkRatio(e){var n,a;const o=e.filter(l=>l.asset.side===re.LONG),r=e.filter(l=>l.asset.side===re.SHORT);if(o.length===0||r.length===0)return 0;const s=!((n=o[0])===null||n===void 0)&&n.asset.coin?this.getMarketPrice(o[0].asset.coin):0,c=!((a=r[0])===null||a===void 0)&&a.asset.coin?this.getMarketPrice(r[0].asset.coin):0;return c>0?s/c:0}calculateNetFundingFromSyncResults(e){return e.reduce((a,o)=>{const r=o.cumFunding.sinceOpen;return a+r},0)}calculateTotalUnrealizedPnlFromSyncResults(e){return e.reduce((n,a)=>n+a.unrealizedPnl,0)}calculateCurrentTotalPositionValue(e){return e.reduce((n,a)=>{const o=this.getMarketPrice(a.asset.coin);return n+a.actualSize*o},0)}calculateEntryTotalPositionValue(e){return e.reduce((n,a)=>n+Number(a.asset.size||0)*Number(a.asset.entryPrice||0),0)}}const Ke=d((t,e,n)=>W(()=>!t||!e||!n?null:new rn(e,n).execute(t),[t,e,n]),"useCalculatedOpenPositions");class Xe{static{d(this,"AccountSummaryCalculator")}constructor(e){this.webData2=e}calculateAccountSummary(e,n,a,o){var r,s,c,l,i,u,h,g,f,S,A;if(!(!((r=this.webData2)===null||r===void 0)&&r.clearinghouseState))return e;const E=this.webData2.clearinghouseState,m=this.calculateTotalLimitOrderValue(n||[]),k=parseFloat(E.withdrawable||"0"),w=Math.max(0,k-m);return{balanceSummary:{crossMaintenanceMarginUsed:E.crossMaintenanceMarginUsed||"0",crossMarginSummary:{accountValue:((s=E.crossMarginSummary)===null||s===void 0?void 0:s.accountValue)||"0",totalMarginUsed:((c=E.crossMarginSummary)===null||c===void 0?void 0:c.totalMarginUsed)||"0",totalNtlPos:((l=E.crossMarginSummary)===null||l===void 0?void 0:l.totalNtlPos)||"0",totalRawUsd:((i=E.crossMarginSummary)===null||i===void 0?void 0:i.totalRawUsd)||"0"},marginSummary:{accountValue:((u=E.marginSummary)===null||u===void 0?void 0:u.accountValue)||"0",totalMarginUsed:((h=E.marginSummary)===null||h===void 0?void 0:h.totalMarginUsed)||"0",totalNtlPos:((g=E.marginSummary)===null||g===void 0?void 0:g.totalNtlPos)||"0",totalRawUsd:((f=E.marginSummary)===null||f===void 0?void 0:f.totalRawUsd)||"0"},time:E.time||Date.now(),withdrawable:w.toString()},agentWallet:{address:a||((S=e?.agentWallet)===null||S===void 0?void 0:S.address)||"",status:o||((A=e?.agentWallet)===null||A===void 0?void 0:A.status)||"UNKNOWN"}}}calculateTotalLimitOrderValue(e){return e?.length?e.filter(a=>a.status==="OPEN"||a.status==="PROCESSING").reduce((a,o)=>a+o.usdValue,0):0}getClearinghouseState(){var e;return((e=this.webData2)===null||e===void 0?void 0:e.clearinghouseState)||null}hasRealTimeData(){var e;return!!(!((e=this.webData2)===null||e===void 0)&&e.clearinghouseState)}}const Qe=d((t,e,n,a,o)=>W(()=>t?n?.clearinghouseState?new Xe(n).calculateAccountSummary(t,e,a,o):t:null,[t,e,n,a,o]),"useCalculatedAccountSummary"),on=d(()=>{const t=Z(X);if(!t)throw new Error("useTradeHistories must be used within a PearHyperliquidProvider");const e=W(()=>t.data.tradeHistories===null&&t.isConnected,[t.data.tradeHistories,t.isConnected]);return{data:t.data.tradeHistories,isLoading:e}},"useTradeHistories"),an=d(()=>{const t=Z(X);if(!t)throw new Error("useOpenPositions must be used within a PearHyperliquidProvider");const e=Ke(t.data.openPositions,t.webData2,t.allMids),n=W(()=>t.isConnected&&(t.data.openPositions===null||!t.webData2||!t.allMids),[t.data.openPositions,t.webData2,t.allMids,t.isConnected]);return{data:e,isLoading:n}},"useOpenPositions"),sn=d(()=>{const t=Z(X);if(!t)throw new Error("useOpenOrders must be used within a PearHyperliquidProvider");const e=W(()=>t.data.openOrders===null&&t.isConnected,[t.data.openOrders,t.isConnected]);return{data:t.data.openOrders,isLoading:e}},"useOpenOrders"),cn=d(()=>{var t,e,n,a;const o=Z(X);if(!o)throw new Error("useAccountSummary must be used within a PearHyperliquidProvider");const r=Qe(o.data.accountSummary,o.data.openOrders,o.webData2,(e=(t=o.data.accountSummary)===null||t===void 0?void 0:t.agentWallet)===null||e===void 0?void 0:e.address,(a=(n=o.data.accountSummary)===null||n===void 0?void 0:n.agentWallet)===null||a===void 0?void 0:a.status),s=W(()=>o.data.accountSummary===null&&o.isConnected,[o.data.accountSummary,o.isConnected]);return{data:r,isLoading:s}},"useAccountSummary");class Ue{static{d(this,"TokenMetadataExtractor")}static extractTokenMetadata(e,n,a,o){if(!n||!a)return null;const r=n.meta.universe.findIndex(O=>O.name===e);if(r===-1)return null;const s=n.meta.universe[r],c=n.assetCtxs[r];if(!c)return null;const l=a.mids[e],i=l?parseFloat(l):0,u=parseFloat(c.prevDayPx),h=i-u,g=u!==0?h/u*100:0,f=parseFloat(c.funding)*100,S=parseFloat(c.markPx),A=parseFloat(c.oraclePx),E=o?.[e],m=E?.leverage,k=E?.maxTradeSzs,w=E?.availableToTrade;return{currentPrice:i,prevDayPrice:u,priceChange24h:h,priceChange24hPercent:g,netFunding:f,maxLeverage:s.maxLeverage,markPrice:S,oraclePrice:A,openInterest:c.openInterest,dayVolume:c.dayNtlVlm,leverage:m,maxTradeSzs:k,availableToTrade:w}}static extractMultipleTokensMetadata(e,n,a,o){const r={};for(const s of e)r[s]=this.extractTokenMetadata(s,n,a,o);return r}static isTokenAvailable(e,n){return n?n.meta.universe.some(a=>a.name===e):!1}}const un=d(()=>{var t;const e=Z(X);if(!e)throw new Error("useTokenSelection must be used within PearHyperliquidProvider");const{webData2:n,allMids:a,activeAssetData:o,tokenSelection:r,setTokenSelection:s}=e,c=W(()=>!!(n&&a),[n,a]),l=W(()=>{if(!c)return!0;const T=[...r.longTokens,...r.shortTokens];return T.length===0?!1:T.some(y=>!y.metadata)},[c,r.longTokens,r.shortTokens]);se(()=>{if(!n||!a)return;const T=[...r.longTokens,...r.shortTokens].map(b=>b.symbol);if(T.length===0)return;const y=Ue.extractMultipleTokensMetadata(T,n,a,o);s(b=>({...b,longTokens:b.longTokens.map(_=>({..._,metadata:y[_.symbol]||void 0})),shortTokens:b.shortTokens.map(_=>({..._,metadata:y[_.symbol]||void 0}))}))},[n,a,o,s]);const i=W(()=>{let T=1,y=1;return r.longTokens.forEach(b=>{var _;if(!((_=b.metadata)===null||_===void 0)&&_.currentPrice&&b.weight>0){const P=b.weight/100;T*=Math.pow(b.metadata.currentPrice,P)}}),r.shortTokens.forEach(b=>{var _;if(!((_=b.metadata)===null||_===void 0)&&_.currentPrice&&b.weight>0){const P=b.weight/100;y*=Math.pow(b.metadata.currentPrice,-P)}}),T*y},[r.longTokens,r.shortTokens]),u=W(()=>{let T=1,y=1;return r.longTokens.forEach(b=>{var _;if(!((_=b.metadata)===null||_===void 0)&&_.prevDayPrice&&b.weight>0){const P=b.weight/100;T*=Math.pow(b.metadata.prevDayPrice,P)}}),r.shortTokens.forEach(b=>{var _;if(!((_=b.metadata)===null||_===void 0)&&_.prevDayPrice&&b.weight>0){const P=b.weight/100;y*=Math.pow(b.metadata.prevDayPrice,-P)}}),T*y},[r.longTokens,r.shortTokens]),h=W(()=>{let T=0;return r.longTokens.forEach(y=>{var b;if(!((b=y.metadata)===null||b===void 0)&&b.netFunding&&y.weight>0){const _=y.weight/100;T+=y.metadata.netFunding*_}}),r.shortTokens.forEach(y=>{var b;if(!((b=y.metadata)===null||b===void 0)&&b.netFunding&&y.weight>0){const _=y.weight/100;T-=y.metadata.netFunding*_}}),T*100},[r.longTokens,r.shortTokens]),g=W(()=>{var T;if(!(!((T=n?.meta)===null||T===void 0)&&T.universe))return 0;const y=[...r.longTokens,...r.shortTokens].map(_=>_.symbol);if(y.length===0)return 0;let b=1/0;return y.forEach(_=>{const P=n.meta.universe.find(M=>M.name===_);P?.maxLeverage&&(b=Math.min(b,P.maxLeverage))}),b===1/0?0:b},[(t=n?.meta)===null||t===void 0?void 0:t.universe,r.longTokens,r.shortTokens]),f=W(()=>10*(r.longTokens.length+r.shortTokens.length),[r.longTokens.length,r.shortTokens.length]),S=W(()=>{const T=[...r.longTokens,...r.shortTokens];if(T.length===0)return!0;const y=T.filter(_=>{var P;return(P=_.metadata)===null||P===void 0?void 0:P.leverage});if(y.length===0||y.length<T.length)return!1;const b=y[0].metadata.leverage;return y.every(_=>_.metadata.leverage.type===b.type&&_.metadata.leverage.value===b.value)},[r.longTokens,r.shortTokens]),A=q(T=>{s(y=>({...y,longTokens:T}))},[s]),E=q(T=>{s(y=>({...y,shortTokens:T}))},[s]),m=q((T,y,b)=>{const _=Math.max(1,Math.min(100,b));s(P=>{var M,D;const z=P.longTokens.reduce(($,v)=>$+v.weight,0),Q=P.shortTokens.reduce(($,v)=>$+v.weight,0);if(T){const $=((M=P.longTokens[y])===null||M===void 0?void 0:M.weight)||0,v=_-$;if(z+v+Q>100){const C=Math.max(1,100-Q-(z-$)),R=[...P.longTokens];return R[y]={...R[y],weight:C},{...P,longTokens:R}}else{const C=[...P.longTokens];return C[y]={...C[y],weight:_},{...P,longTokens:C}}}else{const $=((D=P.shortTokens[y])===null||D===void 0?void 0:D.weight)||0,v=_-$,p=Q+v;if(z+p>100){const C=Math.max(1,100-z-(Q-$)),R=[...P.shortTokens];return R[y]={...R[y],weight:C},{...P,shortTokens:R}}else{const C=[...P.shortTokens];return C[y]={...C[y],weight:_},{...P,shortTokens:C}}}})},[s]),k=q(T=>{const b=(T?r.longTokens:r.shortTokens).length;s(_=>({..._,selectorConfig:{isLong:T,index:b},openTokenSelector:!0}))},[r.longTokens,r.shortTokens,s]),w=q((T,y)=>{s(b=>{if(T){const _=b.longTokens.filter((P,M)=>M!==y);return{...b,longTokens:_}}else{const _=b.shortTokens.filter((P,M)=>M!==y);return{...b,shortTokens:_}}})},[s]),O=q(T=>{s(y=>({...y,openTokenSelector:T}))},[s]),I=q(T=>{s(y=>({...y,selectorConfig:T}))},[s]),j=q(T=>{s(y=>({...y,openConflictModal:T}))},[s]),N=q(T=>{s(y=>({...y,conflicts:T}))},[s]),U=q(()=>{s(T=>({...T,longTokens:[{symbol:"HYPE",weight:25},{symbol:"BTC",weight:25}],shortTokens:[{symbol:"AVAX",weight:10},{symbol:"SEI",weight:10},{symbol:"ADA",weight:10},{symbol:"TRUMP",weight:10},{symbol:"SUI",weight:10}],openTokenSelector:!1,selectorConfig:null,openConflictModal:!1,leverageMatched:!1}))},[s]),J=q(T=>{if(!r.selectorConfig)return;const{isLong:y,index:b}=r.selectorConfig,_=y?r.longTokens:r.shortTokens;if(_.some(M=>M.symbol===T))return;const P=Ue.extractTokenMetadata(T,n,a,o);s(M=>{if(b>=_.length){const D=M.longTokens.reduce((C,R)=>C+R.weight,0),z=M.shortTokens.reduce((C,R)=>C+R.weight,0),Q=D+z,$=Math.max(1,100-Q),v=Math.min(20,$),p={symbol:T,weight:v,metadata:P||void 0};return y?{...M,longTokens:[...M.longTokens,p]}:{...M,shortTokens:[...M.shortTokens,p]}}else if(y){const D=[...M.longTokens];return D[b]={...D[b],symbol:T,metadata:P||void 0},{...M,longTokens:D}}else{const D=[...M.shortTokens];return D[b]={...D[b],symbol:T,metadata:P||void 0},{...M,shortTokens:D}}})},[r.selectorConfig,r.longTokens,r.shortTokens,n,a,o,s]);return{longTokens:r.longTokens,shortTokens:r.shortTokens,openTokenSelector:r.openTokenSelector,selectorConfig:r.selectorConfig,openConflictModal:r.openConflictModal,conflicts:r.conflicts,isLoading:l,isPriceDataReady:c,weightedRatio:i,weightedRatio24h:u,sumNetFunding:h,maxLeverage:g,minMargin:f,leverageMatched:S,setLongTokens:A,setShortTokens:E,updateTokenWeight:m,addToken:k,removeToken:w,handleTokenSelect:J,setOpenTokenSelector:O,setSelectorConfig:I,setOpenConflictModal:j,setConflicts:N,resetToDefaults:U}},"useTokenSelection"),ln=d(()=>{const t=Z(X);if(!t)throw new Error("useWebData2 must be used within a PearHyperliquidProvider");return{webData2:t.webData2,allMids:t.allMids,isConnected:t.nativeIsConnected,connectionStatus:t.nativeConnectionStatus,error:t.nativeLastError}},"useWebData2");class dn{static{d(this,"ConflictDetector")}static detectConflicts(e,n,a){const o=[];return a&&(e.forEach(r=>{a.find(c=>{var l;const i=c.coin||c.symbol||c.asset,u=(l=c.side)===null||l===void 0?void 0:l.toLowerCase();return i===r.symbol&&(u==="short"||u==="sell")})&&o.push({symbol:r.symbol,conflictType:"short",conflictMessage:`${r.symbol} Long conflicts with existing ${r.symbol} Short position`})}),n.forEach(r=>{a.find(c=>{var l;const i=c.coin||c.symbol||c.asset,u=(l=c.side)===null||l===void 0?void 0:l.toLowerCase();return i===r.symbol&&(u==="long"||u==="buy")})&&o.push({symbol:r.symbol,conflictType:"long",conflictMessage:`${r.symbol} Short conflicts with existing ${r.symbol} Long position`})})),o}}export{Xe as AccountSummaryCalculator,dn as ConflictDetector,Me as PearHyperliquidClient,Zt as PearHyperliquidProvider,je as PearMigrationSDK,Ue as TokenMetadataExtractor,Me as default,cn as useAccountSummary,nn as useAddress,Qe as useCalculatedAccountSummary,Ke as useCalculatedOpenPositions,Be as useHyperliquidNativeWebSocket,Ye as useHyperliquidWebSocket,tn as useMigrationSDK,sn as useOpenOrders,an as useOpenPositions,en as usePearHyperliquidClient,un as useTokenSelection,on as useTradeHistories,ln as useWebData2};
|
|
310
|
+
*/
|
|
311
|
+
|
|
312
|
+
var hasRequiredReactJsxRuntime_development;
|
|
313
|
+
|
|
314
|
+
function requireReactJsxRuntime_development () {
|
|
315
|
+
if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
|
|
316
|
+
hasRequiredReactJsxRuntime_development = 1;
|
|
317
|
+
"production" !== process.env.NODE_ENV &&
|
|
318
|
+
(function () {
|
|
319
|
+
function getComponentNameFromType(type) {
|
|
320
|
+
if (null == type) return null;
|
|
321
|
+
if ("function" === typeof type)
|
|
322
|
+
return type.$$typeof === REACT_CLIENT_REFERENCE
|
|
323
|
+
? null
|
|
324
|
+
: type.displayName || type.name || null;
|
|
325
|
+
if ("string" === typeof type) return type;
|
|
326
|
+
switch (type) {
|
|
327
|
+
case REACT_FRAGMENT_TYPE:
|
|
328
|
+
return "Fragment";
|
|
329
|
+
case REACT_PROFILER_TYPE:
|
|
330
|
+
return "Profiler";
|
|
331
|
+
case REACT_STRICT_MODE_TYPE:
|
|
332
|
+
return "StrictMode";
|
|
333
|
+
case REACT_SUSPENSE_TYPE:
|
|
334
|
+
return "Suspense";
|
|
335
|
+
case REACT_SUSPENSE_LIST_TYPE:
|
|
336
|
+
return "SuspenseList";
|
|
337
|
+
case REACT_ACTIVITY_TYPE:
|
|
338
|
+
return "Activity";
|
|
339
|
+
}
|
|
340
|
+
if ("object" === typeof type)
|
|
341
|
+
switch (
|
|
342
|
+
("number" === typeof type.tag &&
|
|
343
|
+
console.error(
|
|
344
|
+
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
345
|
+
),
|
|
346
|
+
type.$$typeof)
|
|
347
|
+
) {
|
|
348
|
+
case REACT_PORTAL_TYPE:
|
|
349
|
+
return "Portal";
|
|
350
|
+
case REACT_CONTEXT_TYPE:
|
|
351
|
+
return (type.displayName || "Context") + ".Provider";
|
|
352
|
+
case REACT_CONSUMER_TYPE:
|
|
353
|
+
return (type._context.displayName || "Context") + ".Consumer";
|
|
354
|
+
case REACT_FORWARD_REF_TYPE:
|
|
355
|
+
var innerType = type.render;
|
|
356
|
+
type = type.displayName;
|
|
357
|
+
type ||
|
|
358
|
+
((type = innerType.displayName || innerType.name || ""),
|
|
359
|
+
(type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef"));
|
|
360
|
+
return type;
|
|
361
|
+
case REACT_MEMO_TYPE:
|
|
362
|
+
return (
|
|
363
|
+
(innerType = type.displayName || null),
|
|
364
|
+
null !== innerType
|
|
365
|
+
? innerType
|
|
366
|
+
: getComponentNameFromType(type.type) || "Memo"
|
|
367
|
+
);
|
|
368
|
+
case REACT_LAZY_TYPE:
|
|
369
|
+
innerType = type._payload;
|
|
370
|
+
type = type._init;
|
|
371
|
+
try {
|
|
372
|
+
return getComponentNameFromType(type(innerType));
|
|
373
|
+
} catch (x) {}
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
function testStringCoercion(value) {
|
|
378
|
+
return "" + value;
|
|
379
|
+
}
|
|
380
|
+
function checkKeyStringCoercion(value) {
|
|
381
|
+
try {
|
|
382
|
+
testStringCoercion(value);
|
|
383
|
+
var JSCompiler_inline_result = !1;
|
|
384
|
+
} catch (e) {
|
|
385
|
+
JSCompiler_inline_result = !0;
|
|
386
|
+
}
|
|
387
|
+
if (JSCompiler_inline_result) {
|
|
388
|
+
JSCompiler_inline_result = console;
|
|
389
|
+
var JSCompiler_temp_const = JSCompiler_inline_result.error;
|
|
390
|
+
var JSCompiler_inline_result$jscomp$0 =
|
|
391
|
+
("function" === typeof Symbol &&
|
|
392
|
+
Symbol.toStringTag &&
|
|
393
|
+
value[Symbol.toStringTag]) ||
|
|
394
|
+
value.constructor.name ||
|
|
395
|
+
"Object";
|
|
396
|
+
JSCompiler_temp_const.call(
|
|
397
|
+
JSCompiler_inline_result,
|
|
398
|
+
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
399
|
+
JSCompiler_inline_result$jscomp$0
|
|
400
|
+
);
|
|
401
|
+
return testStringCoercion(value);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function getTaskName(type) {
|
|
405
|
+
if (type === REACT_FRAGMENT_TYPE) return "<>";
|
|
406
|
+
if (
|
|
407
|
+
"object" === typeof type &&
|
|
408
|
+
null !== type &&
|
|
409
|
+
type.$$typeof === REACT_LAZY_TYPE
|
|
410
|
+
)
|
|
411
|
+
return "<...>";
|
|
412
|
+
try {
|
|
413
|
+
var name = getComponentNameFromType(type);
|
|
414
|
+
return name ? "<" + name + ">" : "<...>";
|
|
415
|
+
} catch (x) {
|
|
416
|
+
return "<...>";
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function getOwner() {
|
|
420
|
+
var dispatcher = ReactSharedInternals.A;
|
|
421
|
+
return null === dispatcher ? null : dispatcher.getOwner();
|
|
422
|
+
}
|
|
423
|
+
function UnknownOwner() {
|
|
424
|
+
return Error("react-stack-top-frame");
|
|
425
|
+
}
|
|
426
|
+
function hasValidKey(config) {
|
|
427
|
+
if (hasOwnProperty.call(config, "key")) {
|
|
428
|
+
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
|
|
429
|
+
if (getter && getter.isReactWarning) return !1;
|
|
430
|
+
}
|
|
431
|
+
return void 0 !== config.key;
|
|
432
|
+
}
|
|
433
|
+
function defineKeyPropWarningGetter(props, displayName) {
|
|
434
|
+
function warnAboutAccessingKey() {
|
|
435
|
+
specialPropKeyWarningShown ||
|
|
436
|
+
((specialPropKeyWarningShown = !0),
|
|
437
|
+
console.error(
|
|
438
|
+
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
439
|
+
displayName
|
|
440
|
+
));
|
|
441
|
+
}
|
|
442
|
+
warnAboutAccessingKey.isReactWarning = !0;
|
|
443
|
+
Object.defineProperty(props, "key", {
|
|
444
|
+
get: warnAboutAccessingKey,
|
|
445
|
+
configurable: !0
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
function elementRefGetterWithDeprecationWarning() {
|
|
449
|
+
var componentName = getComponentNameFromType(this.type);
|
|
450
|
+
didWarnAboutElementRef[componentName] ||
|
|
451
|
+
((didWarnAboutElementRef[componentName] = !0),
|
|
452
|
+
console.error(
|
|
453
|
+
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
454
|
+
));
|
|
455
|
+
componentName = this.props.ref;
|
|
456
|
+
return void 0 !== componentName ? componentName : null;
|
|
457
|
+
}
|
|
458
|
+
function ReactElement(
|
|
459
|
+
type,
|
|
460
|
+
key,
|
|
461
|
+
self,
|
|
462
|
+
source,
|
|
463
|
+
owner,
|
|
464
|
+
props,
|
|
465
|
+
debugStack,
|
|
466
|
+
debugTask
|
|
467
|
+
) {
|
|
468
|
+
self = props.ref;
|
|
469
|
+
type = {
|
|
470
|
+
$$typeof: REACT_ELEMENT_TYPE,
|
|
471
|
+
type: type,
|
|
472
|
+
key: key,
|
|
473
|
+
props: props,
|
|
474
|
+
_owner: owner
|
|
475
|
+
};
|
|
476
|
+
null !== (void 0 !== self ? self : null)
|
|
477
|
+
? Object.defineProperty(type, "ref", {
|
|
478
|
+
enumerable: !1,
|
|
479
|
+
get: elementRefGetterWithDeprecationWarning
|
|
480
|
+
})
|
|
481
|
+
: Object.defineProperty(type, "ref", { enumerable: !1, value: null });
|
|
482
|
+
type._store = {};
|
|
483
|
+
Object.defineProperty(type._store, "validated", {
|
|
484
|
+
configurable: !1,
|
|
485
|
+
enumerable: !1,
|
|
486
|
+
writable: !0,
|
|
487
|
+
value: 0
|
|
488
|
+
});
|
|
489
|
+
Object.defineProperty(type, "_debugInfo", {
|
|
490
|
+
configurable: !1,
|
|
491
|
+
enumerable: !1,
|
|
492
|
+
writable: !0,
|
|
493
|
+
value: null
|
|
494
|
+
});
|
|
495
|
+
Object.defineProperty(type, "_debugStack", {
|
|
496
|
+
configurable: !1,
|
|
497
|
+
enumerable: !1,
|
|
498
|
+
writable: !0,
|
|
499
|
+
value: debugStack
|
|
500
|
+
});
|
|
501
|
+
Object.defineProperty(type, "_debugTask", {
|
|
502
|
+
configurable: !1,
|
|
503
|
+
enumerable: !1,
|
|
504
|
+
writable: !0,
|
|
505
|
+
value: debugTask
|
|
506
|
+
});
|
|
507
|
+
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
|
|
508
|
+
return type;
|
|
509
|
+
}
|
|
510
|
+
function jsxDEVImpl(
|
|
511
|
+
type,
|
|
512
|
+
config,
|
|
513
|
+
maybeKey,
|
|
514
|
+
isStaticChildren,
|
|
515
|
+
source,
|
|
516
|
+
self,
|
|
517
|
+
debugStack,
|
|
518
|
+
debugTask
|
|
519
|
+
) {
|
|
520
|
+
var children = config.children;
|
|
521
|
+
if (void 0 !== children)
|
|
522
|
+
if (isStaticChildren)
|
|
523
|
+
if (isArrayImpl(children)) {
|
|
524
|
+
for (
|
|
525
|
+
isStaticChildren = 0;
|
|
526
|
+
isStaticChildren < children.length;
|
|
527
|
+
isStaticChildren++
|
|
528
|
+
)
|
|
529
|
+
validateChildKeys(children[isStaticChildren]);
|
|
530
|
+
Object.freeze && Object.freeze(children);
|
|
531
|
+
} else
|
|
532
|
+
console.error(
|
|
533
|
+
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
534
|
+
);
|
|
535
|
+
else validateChildKeys(children);
|
|
536
|
+
if (hasOwnProperty.call(config, "key")) {
|
|
537
|
+
children = getComponentNameFromType(type);
|
|
538
|
+
var keys = Object.keys(config).filter(function (k) {
|
|
539
|
+
return "key" !== k;
|
|
540
|
+
});
|
|
541
|
+
isStaticChildren =
|
|
542
|
+
0 < keys.length
|
|
543
|
+
? "{key: someKey, " + keys.join(": ..., ") + ": ...}"
|
|
544
|
+
: "{key: someKey}";
|
|
545
|
+
didWarnAboutKeySpread[children + isStaticChildren] ||
|
|
546
|
+
((keys =
|
|
547
|
+
0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"),
|
|
548
|
+
console.error(
|
|
549
|
+
'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
|
|
550
|
+
isStaticChildren,
|
|
551
|
+
children,
|
|
552
|
+
keys,
|
|
553
|
+
children
|
|
554
|
+
),
|
|
555
|
+
(didWarnAboutKeySpread[children + isStaticChildren] = !0));
|
|
556
|
+
}
|
|
557
|
+
children = null;
|
|
558
|
+
void 0 !== maybeKey &&
|
|
559
|
+
(checkKeyStringCoercion(maybeKey), (children = "" + maybeKey));
|
|
560
|
+
hasValidKey(config) &&
|
|
561
|
+
(checkKeyStringCoercion(config.key), (children = "" + config.key));
|
|
562
|
+
if ("key" in config) {
|
|
563
|
+
maybeKey = {};
|
|
564
|
+
for (var propName in config)
|
|
565
|
+
"key" !== propName && (maybeKey[propName] = config[propName]);
|
|
566
|
+
} else maybeKey = config;
|
|
567
|
+
children &&
|
|
568
|
+
defineKeyPropWarningGetter(
|
|
569
|
+
maybeKey,
|
|
570
|
+
"function" === typeof type
|
|
571
|
+
? type.displayName || type.name || "Unknown"
|
|
572
|
+
: type
|
|
573
|
+
);
|
|
574
|
+
return ReactElement(
|
|
575
|
+
type,
|
|
576
|
+
children,
|
|
577
|
+
self,
|
|
578
|
+
source,
|
|
579
|
+
getOwner(),
|
|
580
|
+
maybeKey,
|
|
581
|
+
debugStack,
|
|
582
|
+
debugTask
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
function validateChildKeys(node) {
|
|
586
|
+
"object" === typeof node &&
|
|
587
|
+
null !== node &&
|
|
588
|
+
node.$$typeof === REACT_ELEMENT_TYPE &&
|
|
589
|
+
node._store &&
|
|
590
|
+
(node._store.validated = 1);
|
|
591
|
+
}
|
|
592
|
+
var React = require$$0,
|
|
593
|
+
REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
|
|
594
|
+
REACT_PORTAL_TYPE = Symbol.for("react.portal"),
|
|
595
|
+
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
|
|
596
|
+
REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
|
|
597
|
+
REACT_PROFILER_TYPE = Symbol.for("react.profiler");
|
|
598
|
+
var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
|
|
599
|
+
REACT_CONTEXT_TYPE = Symbol.for("react.context"),
|
|
600
|
+
REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
|
|
601
|
+
REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
|
|
602
|
+
REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"),
|
|
603
|
+
REACT_MEMO_TYPE = Symbol.for("react.memo"),
|
|
604
|
+
REACT_LAZY_TYPE = Symbol.for("react.lazy"),
|
|
605
|
+
REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),
|
|
606
|
+
REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"),
|
|
607
|
+
ReactSharedInternals =
|
|
608
|
+
React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
|
|
609
|
+
hasOwnProperty = Object.prototype.hasOwnProperty,
|
|
610
|
+
isArrayImpl = Array.isArray,
|
|
611
|
+
createTask = console.createTask
|
|
612
|
+
? console.createTask
|
|
613
|
+
: function () {
|
|
614
|
+
return null;
|
|
615
|
+
};
|
|
616
|
+
React = {
|
|
617
|
+
react_stack_bottom_frame: function (callStackForError) {
|
|
618
|
+
return callStackForError();
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
var specialPropKeyWarningShown;
|
|
622
|
+
var didWarnAboutElementRef = {};
|
|
623
|
+
var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(
|
|
624
|
+
React,
|
|
625
|
+
UnknownOwner
|
|
626
|
+
)();
|
|
627
|
+
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
628
|
+
var didWarnAboutKeySpread = {};
|
|
629
|
+
reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
|
|
630
|
+
reactJsxRuntime_development.jsx = function (type, config, maybeKey, source, self) {
|
|
631
|
+
var trackActualOwner =
|
|
632
|
+
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
|
|
633
|
+
return jsxDEVImpl(
|
|
634
|
+
type,
|
|
635
|
+
config,
|
|
636
|
+
maybeKey,
|
|
637
|
+
!1,
|
|
638
|
+
source,
|
|
639
|
+
self,
|
|
640
|
+
trackActualOwner
|
|
641
|
+
? Error("react-stack-top-frame")
|
|
642
|
+
: unknownOwnerDebugStack,
|
|
643
|
+
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
|
|
644
|
+
);
|
|
645
|
+
};
|
|
646
|
+
reactJsxRuntime_development.jsxs = function (type, config, maybeKey, source, self) {
|
|
647
|
+
var trackActualOwner =
|
|
648
|
+
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
|
|
649
|
+
return jsxDEVImpl(
|
|
650
|
+
type,
|
|
651
|
+
config,
|
|
652
|
+
maybeKey,
|
|
653
|
+
!0,
|
|
654
|
+
source,
|
|
655
|
+
self,
|
|
656
|
+
trackActualOwner
|
|
657
|
+
? Error("react-stack-top-frame")
|
|
658
|
+
: unknownOwnerDebugStack,
|
|
659
|
+
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
|
|
660
|
+
);
|
|
661
|
+
};
|
|
662
|
+
})();
|
|
663
|
+
return reactJsxRuntime_development;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (process.env.NODE_ENV === 'production') {
|
|
667
|
+
jsxRuntime.exports = requireReactJsxRuntime_production();
|
|
668
|
+
} else {
|
|
669
|
+
jsxRuntime.exports = requireReactJsxRuntime_development();
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
var jsxRuntimeExports = jsxRuntime.exports;
|
|
673
|
+
|
|
674
|
+
var dist = {};
|
|
675
|
+
|
|
676
|
+
var useWebsocket = {};
|
|
677
|
+
|
|
678
|
+
var constants = {};
|
|
679
|
+
|
|
680
|
+
(function (exports) {
|
|
681
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
682
|
+
exports.isEventSourceSupported = exports.isReactNative = exports.ReadyState = exports.DEFAULT_HEARTBEAT = exports.UNPARSABLE_JSON_OBJECT = exports.DEFAULT_RECONNECT_INTERVAL_MS = exports.DEFAULT_RECONNECT_LIMIT = exports.SOCKET_IO_PING_CODE = exports.SOCKET_IO_PATH = exports.SOCKET_IO_PING_INTERVAL = exports.DEFAULT_EVENT_SOURCE_OPTIONS = exports.EMPTY_EVENT_HANDLERS = exports.DEFAULT_OPTIONS = void 0;
|
|
683
|
+
var MILLISECONDS = 1;
|
|
684
|
+
var SECONDS = 1000 * MILLISECONDS;
|
|
685
|
+
exports.DEFAULT_OPTIONS = {};
|
|
686
|
+
exports.EMPTY_EVENT_HANDLERS = {};
|
|
687
|
+
exports.DEFAULT_EVENT_SOURCE_OPTIONS = {
|
|
688
|
+
withCredentials: false,
|
|
689
|
+
events: exports.EMPTY_EVENT_HANDLERS,
|
|
690
|
+
};
|
|
691
|
+
exports.SOCKET_IO_PING_INTERVAL = 25 * SECONDS;
|
|
692
|
+
exports.SOCKET_IO_PATH = '/socket.io/?EIO=3&transport=websocket';
|
|
693
|
+
exports.SOCKET_IO_PING_CODE = '2';
|
|
694
|
+
exports.DEFAULT_RECONNECT_LIMIT = 20;
|
|
695
|
+
exports.DEFAULT_RECONNECT_INTERVAL_MS = 5000;
|
|
696
|
+
exports.UNPARSABLE_JSON_OBJECT = {};
|
|
697
|
+
exports.DEFAULT_HEARTBEAT = {
|
|
698
|
+
message: 'ping',
|
|
699
|
+
timeout: 60000,
|
|
700
|
+
interval: 25000,
|
|
701
|
+
};
|
|
702
|
+
var ReadyState;
|
|
703
|
+
(function (ReadyState) {
|
|
704
|
+
ReadyState[ReadyState["UNINSTANTIATED"] = -1] = "UNINSTANTIATED";
|
|
705
|
+
ReadyState[ReadyState["CONNECTING"] = 0] = "CONNECTING";
|
|
706
|
+
ReadyState[ReadyState["OPEN"] = 1] = "OPEN";
|
|
707
|
+
ReadyState[ReadyState["CLOSING"] = 2] = "CLOSING";
|
|
708
|
+
ReadyState[ReadyState["CLOSED"] = 3] = "CLOSED";
|
|
709
|
+
})(ReadyState || (exports.ReadyState = ReadyState = {}));
|
|
710
|
+
var eventSourceSupported = function () {
|
|
711
|
+
try {
|
|
712
|
+
return 'EventSource' in globalThis;
|
|
713
|
+
}
|
|
714
|
+
catch (e) {
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
exports.isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
719
|
+
exports.isEventSourceSupported = !exports.isReactNative && eventSourceSupported();
|
|
720
|
+
|
|
721
|
+
} (constants));
|
|
722
|
+
|
|
723
|
+
var createOrJoin = {};
|
|
724
|
+
|
|
725
|
+
var globals = {};
|
|
726
|
+
|
|
727
|
+
(function (exports) {
|
|
728
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
729
|
+
exports.resetWebSockets = exports.sharedWebSockets = void 0;
|
|
730
|
+
exports.sharedWebSockets = {};
|
|
731
|
+
var resetWebSockets = function (url) {
|
|
732
|
+
if (url && exports.sharedWebSockets.hasOwnProperty(url)) {
|
|
733
|
+
delete exports.sharedWebSockets[url];
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
for (var url_1 in exports.sharedWebSockets) {
|
|
737
|
+
if (exports.sharedWebSockets.hasOwnProperty(url_1)) {
|
|
738
|
+
delete exports.sharedWebSockets[url_1];
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
exports.resetWebSockets = resetWebSockets;
|
|
744
|
+
|
|
745
|
+
} (globals));
|
|
746
|
+
|
|
747
|
+
var attachListener = {};
|
|
748
|
+
|
|
749
|
+
var socketIo = {};
|
|
750
|
+
|
|
751
|
+
Object.defineProperty(socketIo, "__esModule", { value: true });
|
|
752
|
+
socketIo.setUpSocketIOPing = socketIo.appendQueryParams = socketIo.parseSocketIOUrl = void 0;
|
|
753
|
+
var constants_1$7 = constants;
|
|
754
|
+
var parseSocketIOUrl = function (url) {
|
|
755
|
+
if (url) {
|
|
756
|
+
var isSecure = /^https|wss/.test(url);
|
|
757
|
+
var strippedProtocol = url.replace(/^(https?|wss?)(:\/\/)?/, '');
|
|
758
|
+
var removedFinalBackSlack = strippedProtocol.replace(/\/$/, '');
|
|
759
|
+
var protocol = isSecure ? 'wss' : 'ws';
|
|
760
|
+
return "".concat(protocol, "://").concat(removedFinalBackSlack).concat(constants_1$7.SOCKET_IO_PATH);
|
|
761
|
+
}
|
|
762
|
+
else if (url === '') {
|
|
763
|
+
var isSecure = /^https/.test(window.location.protocol);
|
|
764
|
+
var protocol = isSecure ? 'wss' : 'ws';
|
|
765
|
+
var port = window.location.port ? ":".concat(window.location.port) : '';
|
|
766
|
+
return "".concat(protocol, "://").concat(window.location.hostname).concat(port).concat(constants_1$7.SOCKET_IO_PATH);
|
|
767
|
+
}
|
|
768
|
+
return url;
|
|
769
|
+
};
|
|
770
|
+
socketIo.parseSocketIOUrl = parseSocketIOUrl;
|
|
771
|
+
var appendQueryParams = function (url, params) {
|
|
772
|
+
if (params === void 0) { params = {}; }
|
|
773
|
+
var hasParamsRegex = /\?([\w]+=[\w]+)/;
|
|
774
|
+
var alreadyHasParams = hasParamsRegex.test(url);
|
|
775
|
+
var stringified = "".concat(Object.entries(params).reduce(function (next, _a) {
|
|
776
|
+
var key = _a[0], value = _a[1];
|
|
777
|
+
return next + "".concat(key, "=").concat(value, "&");
|
|
778
|
+
}, '').slice(0, -1));
|
|
779
|
+
return "".concat(url).concat(alreadyHasParams ? '&' : '?').concat(stringified);
|
|
780
|
+
};
|
|
781
|
+
socketIo.appendQueryParams = appendQueryParams;
|
|
782
|
+
var setUpSocketIOPing = function (sendMessage, interval) {
|
|
783
|
+
if (interval === void 0) { interval = constants_1$7.SOCKET_IO_PING_INTERVAL; }
|
|
784
|
+
var ping = function () { return sendMessage(constants_1$7.SOCKET_IO_PING_CODE); };
|
|
785
|
+
return window.setInterval(ping, interval);
|
|
786
|
+
};
|
|
787
|
+
socketIo.setUpSocketIOPing = setUpSocketIOPing;
|
|
788
|
+
|
|
789
|
+
var heartbeat$1 = {};
|
|
790
|
+
|
|
791
|
+
Object.defineProperty(heartbeat$1, "__esModule", { value: true });
|
|
792
|
+
heartbeat$1.heartbeat = heartbeat;
|
|
793
|
+
var constants_1$6 = constants;
|
|
794
|
+
function getLastMessageTime(lastMessageTime) {
|
|
795
|
+
if (Array.isArray(lastMessageTime)) {
|
|
796
|
+
return lastMessageTime.reduce(function (p, c) { return (p.current > c.current) ? p : c; }).current;
|
|
797
|
+
}
|
|
798
|
+
return lastMessageTime.current;
|
|
799
|
+
}
|
|
800
|
+
function heartbeat(ws, lastMessageTime, options) {
|
|
801
|
+
var _a = options || {}, _b = _a.interval, interval = _b === void 0 ? constants_1$6.DEFAULT_HEARTBEAT.interval : _b, _c = _a.timeout, timeout = _c === void 0 ? constants_1$6.DEFAULT_HEARTBEAT.timeout : _c, _d = _a.message, message = _d === void 0 ? constants_1$6.DEFAULT_HEARTBEAT.message : _d;
|
|
802
|
+
// how often check interval between ping messages
|
|
803
|
+
// minimum is 100ms
|
|
804
|
+
// maximum is ${interval / 10}ms
|
|
805
|
+
var intervalCheck = Math.max(100, interval / 10);
|
|
806
|
+
var lastPingSentAt = Date.now();
|
|
807
|
+
var heartbeatInterval = setInterval(function () {
|
|
808
|
+
var timeNow = Date.now();
|
|
809
|
+
var lastMessageReceivedAt = getLastMessageTime(lastMessageTime);
|
|
810
|
+
if (lastMessageReceivedAt + timeout <= timeNow) {
|
|
811
|
+
console.warn("Heartbeat timed out, closing connection, last message received ".concat(timeNow - lastMessageReceivedAt, "ms ago, last ping sent ").concat(timeNow - lastPingSentAt, "ms ago"));
|
|
812
|
+
ws.close();
|
|
813
|
+
}
|
|
814
|
+
else {
|
|
815
|
+
if (lastMessageReceivedAt + interval <= timeNow && lastPingSentAt + interval <= timeNow) {
|
|
816
|
+
try {
|
|
817
|
+
if (typeof message === 'function') {
|
|
818
|
+
ws.send(message());
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
ws.send(message);
|
|
822
|
+
}
|
|
823
|
+
lastPingSentAt = timeNow;
|
|
824
|
+
}
|
|
825
|
+
catch (err) {
|
|
826
|
+
console.error("Heartbeat failed, closing connection", err instanceof Error ? err.message : err);
|
|
827
|
+
ws.close();
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}, intervalCheck);
|
|
832
|
+
ws.addEventListener("close", function () {
|
|
833
|
+
clearInterval(heartbeatInterval);
|
|
834
|
+
});
|
|
835
|
+
return function () { };
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
var util = {};
|
|
839
|
+
|
|
840
|
+
var manageSubscribers = {};
|
|
841
|
+
|
|
842
|
+
(function (exports) {
|
|
843
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
844
|
+
exports.resetSubscribers = exports.removeSubscriber = exports.addSubscriber = exports.hasSubscribers = exports.getSubscribers = void 0;
|
|
845
|
+
var subscribers = {};
|
|
846
|
+
var EMPTY_LIST = [];
|
|
847
|
+
var getSubscribers = function (url) {
|
|
848
|
+
if ((0, exports.hasSubscribers)(url)) {
|
|
849
|
+
return Array.from(subscribers[url]);
|
|
850
|
+
}
|
|
851
|
+
return EMPTY_LIST;
|
|
852
|
+
};
|
|
853
|
+
exports.getSubscribers = getSubscribers;
|
|
854
|
+
var hasSubscribers = function (url) {
|
|
855
|
+
var _a;
|
|
856
|
+
return ((_a = subscribers[url]) === null || _a === void 0 ? void 0 : _a.size) > 0;
|
|
857
|
+
};
|
|
858
|
+
exports.hasSubscribers = hasSubscribers;
|
|
859
|
+
var addSubscriber = function (url, subscriber) {
|
|
860
|
+
subscribers[url] = subscribers[url] || new Set();
|
|
861
|
+
subscribers[url].add(subscriber);
|
|
862
|
+
};
|
|
863
|
+
exports.addSubscriber = addSubscriber;
|
|
864
|
+
var removeSubscriber = function (url, subscriber) {
|
|
865
|
+
subscribers[url].delete(subscriber);
|
|
866
|
+
};
|
|
867
|
+
exports.removeSubscriber = removeSubscriber;
|
|
868
|
+
var resetSubscribers = function (url) {
|
|
869
|
+
if (url && subscribers.hasOwnProperty(url)) {
|
|
870
|
+
delete subscribers[url];
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
for (var url_1 in subscribers) {
|
|
874
|
+
if (subscribers.hasOwnProperty(url_1)) {
|
|
875
|
+
delete subscribers[url_1];
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
exports.resetSubscribers = resetSubscribers;
|
|
881
|
+
|
|
882
|
+
} (manageSubscribers));
|
|
883
|
+
|
|
884
|
+
Object.defineProperty(util, "__esModule", { value: true });
|
|
885
|
+
util.assertIsWebSocket = assertIsWebSocket;
|
|
886
|
+
util.resetGlobalState = resetGlobalState;
|
|
887
|
+
var globals_1$2 = globals;
|
|
888
|
+
var manage_subscribers_1$2 = manageSubscribers;
|
|
889
|
+
function assertIsWebSocket(webSocketInstance, skip) {
|
|
890
|
+
if (!skip && webSocketInstance instanceof WebSocket === false)
|
|
891
|
+
throw new Error('');
|
|
892
|
+
}
|
|
893
|
+
function resetGlobalState(url) {
|
|
894
|
+
(0, manage_subscribers_1$2.resetSubscribers)(url);
|
|
895
|
+
(0, globals_1$2.resetWebSockets)(url);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
var __assign$4 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
899
|
+
__assign$4 = Object.assign || function(t) {
|
|
900
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
901
|
+
s = arguments[i];
|
|
902
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
903
|
+
t[p] = s[p];
|
|
904
|
+
}
|
|
905
|
+
return t;
|
|
906
|
+
};
|
|
907
|
+
return __assign$4.apply(this, arguments);
|
|
908
|
+
};
|
|
909
|
+
Object.defineProperty(attachListener, "__esModule", { value: true });
|
|
910
|
+
attachListener.attachListeners = void 0;
|
|
911
|
+
var socket_io_1$1 = socketIo;
|
|
912
|
+
var heartbeat_1$1 = heartbeat$1;
|
|
913
|
+
var constants_1$5 = constants;
|
|
914
|
+
var util_1$1 = util;
|
|
915
|
+
var bindMessageHandler$1 = function (webSocketInstance, optionsRef, setLastMessage, lastMessageTime) {
|
|
916
|
+
webSocketInstance.onmessage = function (message) {
|
|
917
|
+
var _a;
|
|
918
|
+
optionsRef.current.onMessage && optionsRef.current.onMessage(message);
|
|
919
|
+
if (typeof (lastMessageTime === null || lastMessageTime === void 0 ? void 0 : lastMessageTime.current) === 'number') {
|
|
920
|
+
lastMessageTime.current = Date.now();
|
|
921
|
+
}
|
|
922
|
+
if (typeof optionsRef.current.filter === 'function' && optionsRef.current.filter(message) !== true) {
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
if (optionsRef.current.heartbeat &&
|
|
926
|
+
typeof optionsRef.current.heartbeat !== "boolean" &&
|
|
927
|
+
((_a = optionsRef.current.heartbeat) === null || _a === void 0 ? void 0 : _a.returnMessage) === message.data) {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
setLastMessage(message);
|
|
931
|
+
};
|
|
932
|
+
};
|
|
933
|
+
var bindOpenHandler$1 = function (webSocketInstance, optionsRef, setReadyState, reconnectCount, lastMessageTime) {
|
|
934
|
+
webSocketInstance.onopen = function (event) {
|
|
935
|
+
optionsRef.current.onOpen && optionsRef.current.onOpen(event);
|
|
936
|
+
reconnectCount.current = 0;
|
|
937
|
+
setReadyState(constants_1$5.ReadyState.OPEN);
|
|
938
|
+
//start heart beat here
|
|
939
|
+
if (optionsRef.current.heartbeat && webSocketInstance instanceof WebSocket) {
|
|
940
|
+
var heartbeatOptions = typeof optionsRef.current.heartbeat === "boolean"
|
|
941
|
+
? undefined
|
|
942
|
+
: optionsRef.current.heartbeat;
|
|
943
|
+
lastMessageTime.current = Date.now();
|
|
944
|
+
(0, heartbeat_1$1.heartbeat)(webSocketInstance, lastMessageTime, heartbeatOptions);
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
};
|
|
948
|
+
var bindCloseHandler$1 = function (webSocketInstance, optionsRef, setReadyState, reconnect, reconnectCount) {
|
|
949
|
+
if (constants_1$5.isEventSourceSupported && webSocketInstance instanceof EventSource) {
|
|
950
|
+
return function () { };
|
|
951
|
+
}
|
|
952
|
+
(0, util_1$1.assertIsWebSocket)(webSocketInstance, optionsRef.current.skipAssert);
|
|
953
|
+
var reconnectTimeout;
|
|
954
|
+
webSocketInstance.onclose = function (event) {
|
|
955
|
+
var _a;
|
|
956
|
+
optionsRef.current.onClose && optionsRef.current.onClose(event);
|
|
957
|
+
setReadyState(constants_1$5.ReadyState.CLOSED);
|
|
958
|
+
if (optionsRef.current.shouldReconnect && optionsRef.current.shouldReconnect(event)) {
|
|
959
|
+
var reconnectAttempts = (_a = optionsRef.current.reconnectAttempts) !== null && _a !== void 0 ? _a : constants_1$5.DEFAULT_RECONNECT_LIMIT;
|
|
960
|
+
if (reconnectCount.current < reconnectAttempts) {
|
|
961
|
+
var nextReconnectInterval = typeof optionsRef.current.reconnectInterval === 'function' ?
|
|
962
|
+
optionsRef.current.reconnectInterval(reconnectCount.current) :
|
|
963
|
+
optionsRef.current.reconnectInterval;
|
|
964
|
+
reconnectTimeout = window.setTimeout(function () {
|
|
965
|
+
reconnectCount.current++;
|
|
966
|
+
reconnect();
|
|
967
|
+
}, nextReconnectInterval !== null && nextReconnectInterval !== void 0 ? nextReconnectInterval : constants_1$5.DEFAULT_RECONNECT_INTERVAL_MS);
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
optionsRef.current.onReconnectStop && optionsRef.current.onReconnectStop(reconnectAttempts);
|
|
971
|
+
console.warn("Max reconnect attempts of ".concat(reconnectAttempts, " exceeded"));
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
return function () { return reconnectTimeout && window.clearTimeout(reconnectTimeout); };
|
|
976
|
+
};
|
|
977
|
+
var bindErrorHandler$1 = function (webSocketInstance, optionsRef, setReadyState, reconnect, reconnectCount) {
|
|
978
|
+
var reconnectTimeout;
|
|
979
|
+
webSocketInstance.onerror = function (error) {
|
|
980
|
+
var _a;
|
|
981
|
+
optionsRef.current.onError && optionsRef.current.onError(error);
|
|
982
|
+
if (constants_1$5.isEventSourceSupported && webSocketInstance instanceof EventSource) {
|
|
983
|
+
optionsRef.current.onClose && optionsRef.current.onClose(__assign$4(__assign$4({}, error), { code: 1006, reason: "An error occurred with the EventSource: ".concat(error), wasClean: false }));
|
|
984
|
+
setReadyState(constants_1$5.ReadyState.CLOSED);
|
|
985
|
+
webSocketInstance.close();
|
|
986
|
+
}
|
|
987
|
+
if (optionsRef.current.retryOnError) {
|
|
988
|
+
if (reconnectCount.current < ((_a = optionsRef.current.reconnectAttempts) !== null && _a !== void 0 ? _a : constants_1$5.DEFAULT_RECONNECT_LIMIT)) {
|
|
989
|
+
var nextReconnectInterval = typeof optionsRef.current.reconnectInterval === 'function' ?
|
|
990
|
+
optionsRef.current.reconnectInterval(reconnectCount.current) :
|
|
991
|
+
optionsRef.current.reconnectInterval;
|
|
992
|
+
reconnectTimeout = window.setTimeout(function () {
|
|
993
|
+
reconnectCount.current++;
|
|
994
|
+
reconnect();
|
|
995
|
+
}, nextReconnectInterval !== null && nextReconnectInterval !== void 0 ? nextReconnectInterval : constants_1$5.DEFAULT_RECONNECT_INTERVAL_MS);
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
optionsRef.current.onReconnectStop && optionsRef.current.onReconnectStop(optionsRef.current.reconnectAttempts);
|
|
999
|
+
console.warn("Max reconnect attempts of ".concat(optionsRef.current.reconnectAttempts, " exceeded"));
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
return function () { return reconnectTimeout && window.clearTimeout(reconnectTimeout); };
|
|
1004
|
+
};
|
|
1005
|
+
var attachListeners = function (webSocketInstance, setters, optionsRef, reconnect, reconnectCount, lastMessageTime, sendMessage) {
|
|
1006
|
+
var setLastMessage = setters.setLastMessage, setReadyState = setters.setReadyState;
|
|
1007
|
+
var interval;
|
|
1008
|
+
var cancelReconnectOnClose;
|
|
1009
|
+
var cancelReconnectOnError;
|
|
1010
|
+
if (optionsRef.current.fromSocketIO) {
|
|
1011
|
+
interval = (0, socket_io_1$1.setUpSocketIOPing)(sendMessage);
|
|
1012
|
+
}
|
|
1013
|
+
bindMessageHandler$1(webSocketInstance, optionsRef, setLastMessage, lastMessageTime);
|
|
1014
|
+
bindOpenHandler$1(webSocketInstance, optionsRef, setReadyState, reconnectCount, lastMessageTime);
|
|
1015
|
+
cancelReconnectOnClose = bindCloseHandler$1(webSocketInstance, optionsRef, setReadyState, reconnect, reconnectCount);
|
|
1016
|
+
cancelReconnectOnError = bindErrorHandler$1(webSocketInstance, optionsRef, setReadyState, reconnect, reconnectCount);
|
|
1017
|
+
return function () {
|
|
1018
|
+
setReadyState(constants_1$5.ReadyState.CLOSING);
|
|
1019
|
+
cancelReconnectOnClose();
|
|
1020
|
+
cancelReconnectOnError();
|
|
1021
|
+
webSocketInstance.close();
|
|
1022
|
+
if (interval)
|
|
1023
|
+
clearInterval(interval);
|
|
1024
|
+
};
|
|
1025
|
+
};
|
|
1026
|
+
attachListener.attachListeners = attachListeners;
|
|
1027
|
+
|
|
1028
|
+
var attachSharedListeners$1 = {};
|
|
1029
|
+
|
|
1030
|
+
var __assign$3 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1031
|
+
__assign$3 = Object.assign || function(t) {
|
|
1032
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1033
|
+
s = arguments[i];
|
|
1034
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1035
|
+
t[p] = s[p];
|
|
1036
|
+
}
|
|
1037
|
+
return t;
|
|
1038
|
+
};
|
|
1039
|
+
return __assign$3.apply(this, arguments);
|
|
1040
|
+
};
|
|
1041
|
+
Object.defineProperty(attachSharedListeners$1, "__esModule", { value: true });
|
|
1042
|
+
attachSharedListeners$1.attachSharedListeners = void 0;
|
|
1043
|
+
var globals_1$1 = globals;
|
|
1044
|
+
var constants_1$4 = constants;
|
|
1045
|
+
var manage_subscribers_1$1 = manageSubscribers;
|
|
1046
|
+
var socket_io_1 = socketIo;
|
|
1047
|
+
var heartbeat_1 = heartbeat$1;
|
|
1048
|
+
var bindMessageHandler = function (webSocketInstance, url, heartbeatOptions) {
|
|
1049
|
+
webSocketInstance.onmessage = function (message) {
|
|
1050
|
+
(0, manage_subscribers_1$1.getSubscribers)(url).forEach(function (subscriber) {
|
|
1051
|
+
var _a;
|
|
1052
|
+
if (subscriber.optionsRef.current.onMessage) {
|
|
1053
|
+
subscriber.optionsRef.current.onMessage(message);
|
|
1054
|
+
}
|
|
1055
|
+
if (typeof ((_a = subscriber === null || subscriber === void 0 ? void 0 : subscriber.lastMessageTime) === null || _a === void 0 ? void 0 : _a.current) === 'number') {
|
|
1056
|
+
subscriber.lastMessageTime.current = Date.now();
|
|
1057
|
+
}
|
|
1058
|
+
if (typeof subscriber.optionsRef.current.filter === 'function' &&
|
|
1059
|
+
subscriber.optionsRef.current.filter(message) !== true) {
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
if (heartbeatOptions &&
|
|
1063
|
+
typeof heartbeatOptions !== "boolean" &&
|
|
1064
|
+
(heartbeatOptions === null || heartbeatOptions === void 0 ? void 0 : heartbeatOptions.returnMessage) === message.data)
|
|
1065
|
+
return;
|
|
1066
|
+
subscriber.setLastMessage(message);
|
|
1067
|
+
});
|
|
1068
|
+
};
|
|
1069
|
+
};
|
|
1070
|
+
var bindOpenHandler = function (webSocketInstance, url, heartbeatOptions) {
|
|
1071
|
+
webSocketInstance.onopen = function (event) {
|
|
1072
|
+
var subscribers = (0, manage_subscribers_1$1.getSubscribers)(url);
|
|
1073
|
+
subscribers.forEach(function (subscriber) {
|
|
1074
|
+
subscriber.reconnectCount.current = 0;
|
|
1075
|
+
if (subscriber.optionsRef.current.onOpen) {
|
|
1076
|
+
subscriber.optionsRef.current.onOpen(event);
|
|
1077
|
+
}
|
|
1078
|
+
subscriber.setReadyState(constants_1$4.ReadyState.OPEN);
|
|
1079
|
+
if (heartbeatOptions && webSocketInstance instanceof WebSocket) {
|
|
1080
|
+
subscriber.lastMessageTime.current = Date.now();
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
if (heartbeatOptions && webSocketInstance instanceof WebSocket) {
|
|
1084
|
+
(0, heartbeat_1.heartbeat)(webSocketInstance, subscribers.map(function (subscriber) { return subscriber.lastMessageTime; }), typeof heartbeatOptions === 'boolean' ? undefined : heartbeatOptions);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
};
|
|
1088
|
+
var bindCloseHandler = function (webSocketInstance, url) {
|
|
1089
|
+
if (webSocketInstance instanceof WebSocket) {
|
|
1090
|
+
webSocketInstance.onclose = function (event) {
|
|
1091
|
+
(0, manage_subscribers_1$1.getSubscribers)(url).forEach(function (subscriber) {
|
|
1092
|
+
if (subscriber.optionsRef.current.onClose) {
|
|
1093
|
+
subscriber.optionsRef.current.onClose(event);
|
|
1094
|
+
}
|
|
1095
|
+
subscriber.setReadyState(constants_1$4.ReadyState.CLOSED);
|
|
1096
|
+
});
|
|
1097
|
+
delete globals_1$1.sharedWebSockets[url];
|
|
1098
|
+
(0, manage_subscribers_1$1.getSubscribers)(url).forEach(function (subscriber) {
|
|
1099
|
+
var _a;
|
|
1100
|
+
if (subscriber.optionsRef.current.shouldReconnect &&
|
|
1101
|
+
subscriber.optionsRef.current.shouldReconnect(event)) {
|
|
1102
|
+
var reconnectAttempts = (_a = subscriber.optionsRef.current.reconnectAttempts) !== null && _a !== void 0 ? _a : constants_1$4.DEFAULT_RECONNECT_LIMIT;
|
|
1103
|
+
if (subscriber.reconnectCount.current < reconnectAttempts) {
|
|
1104
|
+
var nextReconnectInterval = typeof subscriber.optionsRef.current.reconnectInterval === 'function' ?
|
|
1105
|
+
subscriber.optionsRef.current.reconnectInterval(subscriber.reconnectCount.current) :
|
|
1106
|
+
subscriber.optionsRef.current.reconnectInterval;
|
|
1107
|
+
setTimeout(function () {
|
|
1108
|
+
subscriber.reconnectCount.current++;
|
|
1109
|
+
subscriber.reconnect.current();
|
|
1110
|
+
}, nextReconnectInterval !== null && nextReconnectInterval !== void 0 ? nextReconnectInterval : constants_1$4.DEFAULT_RECONNECT_INTERVAL_MS);
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
subscriber.optionsRef.current.onReconnectStop && subscriber.optionsRef.current.onReconnectStop(subscriber.optionsRef.current.reconnectAttempts);
|
|
1114
|
+
console.warn("Max reconnect attempts of ".concat(reconnectAttempts, " exceeded"));
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
var bindErrorHandler = function (webSocketInstance, url) {
|
|
1122
|
+
webSocketInstance.onerror = function (error) {
|
|
1123
|
+
(0, manage_subscribers_1$1.getSubscribers)(url).forEach(function (subscriber) {
|
|
1124
|
+
if (subscriber.optionsRef.current.onError) {
|
|
1125
|
+
subscriber.optionsRef.current.onError(error);
|
|
1126
|
+
}
|
|
1127
|
+
if (constants_1$4.isEventSourceSupported && webSocketInstance instanceof EventSource) {
|
|
1128
|
+
subscriber.optionsRef.current.onClose && subscriber.optionsRef.current.onClose(__assign$3(__assign$3({}, error), { code: 1006, reason: "An error occurred with the EventSource: ".concat(error), wasClean: false }));
|
|
1129
|
+
subscriber.setReadyState(constants_1$4.ReadyState.CLOSED);
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
if (constants_1$4.isEventSourceSupported && webSocketInstance instanceof EventSource) {
|
|
1133
|
+
webSocketInstance.close();
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
};
|
|
1137
|
+
var attachSharedListeners = function (webSocketInstance, url, optionsRef, sendMessage) {
|
|
1138
|
+
var interval;
|
|
1139
|
+
if (optionsRef.current.fromSocketIO) {
|
|
1140
|
+
interval = (0, socket_io_1.setUpSocketIOPing)(sendMessage);
|
|
1141
|
+
}
|
|
1142
|
+
bindMessageHandler(webSocketInstance, url, optionsRef.current.heartbeat);
|
|
1143
|
+
bindCloseHandler(webSocketInstance, url);
|
|
1144
|
+
bindOpenHandler(webSocketInstance, url, optionsRef.current.heartbeat);
|
|
1145
|
+
bindErrorHandler(webSocketInstance, url);
|
|
1146
|
+
return function () {
|
|
1147
|
+
if (interval)
|
|
1148
|
+
clearInterval(interval);
|
|
1149
|
+
};
|
|
1150
|
+
};
|
|
1151
|
+
attachSharedListeners$1.attachSharedListeners = attachSharedListeners;
|
|
1152
|
+
|
|
1153
|
+
Object.defineProperty(createOrJoin, "__esModule", { value: true });
|
|
1154
|
+
createOrJoin.createOrJoinSocket = void 0;
|
|
1155
|
+
var globals_1 = globals;
|
|
1156
|
+
var constants_1$3 = constants;
|
|
1157
|
+
var attach_listener_1 = attachListener;
|
|
1158
|
+
var attach_shared_listeners_1 = attachSharedListeners$1;
|
|
1159
|
+
var manage_subscribers_1 = manageSubscribers;
|
|
1160
|
+
//TODO ensure that all onClose callbacks are called
|
|
1161
|
+
var cleanSubscribers = function (url, subscriber, optionsRef, setReadyState, clearSocketIoPingInterval) {
|
|
1162
|
+
return function () {
|
|
1163
|
+
(0, manage_subscribers_1.removeSubscriber)(url, subscriber);
|
|
1164
|
+
if (!(0, manage_subscribers_1.hasSubscribers)(url)) {
|
|
1165
|
+
try {
|
|
1166
|
+
var socketLike = globals_1.sharedWebSockets[url];
|
|
1167
|
+
if (socketLike instanceof WebSocket) {
|
|
1168
|
+
socketLike.onclose = function (event) {
|
|
1169
|
+
if (optionsRef.current.onClose) {
|
|
1170
|
+
optionsRef.current.onClose(event);
|
|
1171
|
+
}
|
|
1172
|
+
setReadyState(constants_1$3.ReadyState.CLOSED);
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
socketLike.close();
|
|
1176
|
+
}
|
|
1177
|
+
catch (e) {
|
|
1178
|
+
}
|
|
1179
|
+
if (clearSocketIoPingInterval)
|
|
1180
|
+
clearSocketIoPingInterval();
|
|
1181
|
+
delete globals_1.sharedWebSockets[url];
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
};
|
|
1185
|
+
var createOrJoinSocket = function (webSocketRef, url, setReadyState, optionsRef, setLastMessage, startRef, reconnectCount, lastMessageTime, sendMessage) {
|
|
1186
|
+
if (!constants_1$3.isEventSourceSupported && optionsRef.current.eventSourceOptions) {
|
|
1187
|
+
if (constants_1$3.isReactNative) {
|
|
1188
|
+
throw new Error('EventSource is not supported in ReactNative');
|
|
1189
|
+
}
|
|
1190
|
+
else {
|
|
1191
|
+
throw new Error('EventSource is not supported');
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
if (optionsRef.current.share) {
|
|
1195
|
+
var clearSocketIoPingInterval = null;
|
|
1196
|
+
if (globals_1.sharedWebSockets[url] === undefined) {
|
|
1197
|
+
globals_1.sharedWebSockets[url] = optionsRef.current.eventSourceOptions ?
|
|
1198
|
+
new EventSource(url, optionsRef.current.eventSourceOptions) :
|
|
1199
|
+
new WebSocket(url, optionsRef.current.protocols);
|
|
1200
|
+
webSocketRef.current = globals_1.sharedWebSockets[url];
|
|
1201
|
+
setReadyState(constants_1$3.ReadyState.CONNECTING);
|
|
1202
|
+
clearSocketIoPingInterval = (0, attach_shared_listeners_1.attachSharedListeners)(globals_1.sharedWebSockets[url], url, optionsRef, sendMessage);
|
|
1203
|
+
}
|
|
1204
|
+
else {
|
|
1205
|
+
webSocketRef.current = globals_1.sharedWebSockets[url];
|
|
1206
|
+
setReadyState(globals_1.sharedWebSockets[url].readyState);
|
|
1207
|
+
}
|
|
1208
|
+
var subscriber = {
|
|
1209
|
+
setLastMessage: setLastMessage,
|
|
1210
|
+
setReadyState: setReadyState,
|
|
1211
|
+
optionsRef: optionsRef,
|
|
1212
|
+
reconnectCount: reconnectCount,
|
|
1213
|
+
lastMessageTime: lastMessageTime,
|
|
1214
|
+
reconnect: startRef,
|
|
1215
|
+
};
|
|
1216
|
+
(0, manage_subscribers_1.addSubscriber)(url, subscriber);
|
|
1217
|
+
return cleanSubscribers(url, subscriber, optionsRef, setReadyState, clearSocketIoPingInterval);
|
|
1218
|
+
}
|
|
1219
|
+
else {
|
|
1220
|
+
webSocketRef.current = optionsRef.current.eventSourceOptions ?
|
|
1221
|
+
new EventSource(url, optionsRef.current.eventSourceOptions) :
|
|
1222
|
+
new WebSocket(url, optionsRef.current.protocols);
|
|
1223
|
+
setReadyState(constants_1$3.ReadyState.CONNECTING);
|
|
1224
|
+
if (!webSocketRef.current) {
|
|
1225
|
+
throw new Error('WebSocket failed to be created');
|
|
1226
|
+
}
|
|
1227
|
+
return (0, attach_listener_1.attachListeners)(webSocketRef.current, {
|
|
1228
|
+
setLastMessage: setLastMessage,
|
|
1229
|
+
setReadyState: setReadyState
|
|
1230
|
+
}, optionsRef, startRef.current, reconnectCount, lastMessageTime, sendMessage);
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
createOrJoin.createOrJoinSocket = createOrJoinSocket;
|
|
1234
|
+
|
|
1235
|
+
var getUrl = {};
|
|
1236
|
+
|
|
1237
|
+
(function (exports) {
|
|
1238
|
+
var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1239
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1240
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1241
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1242
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1243
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1244
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1245
|
+
});
|
|
1246
|
+
};
|
|
1247
|
+
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
|
|
1248
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
1249
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
1250
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
1251
|
+
function step(op) {
|
|
1252
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
1253
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
1254
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
1255
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
1256
|
+
switch (op[0]) {
|
|
1257
|
+
case 0: case 1: t = op; break;
|
|
1258
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
1259
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
1260
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
1261
|
+
default:
|
|
1262
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
1263
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
1264
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
1265
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
1266
|
+
if (t[2]) _.ops.pop();
|
|
1267
|
+
_.trys.pop(); continue;
|
|
1268
|
+
}
|
|
1269
|
+
op = body.call(thisArg, _);
|
|
1270
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
1271
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
var __spreadArray = (commonjsGlobal && commonjsGlobal.__spreadArray) || function (to, from, pack) {
|
|
1275
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
1276
|
+
if (ar || !(i in from)) {
|
|
1277
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
1278
|
+
ar[i] = from[i];
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
1282
|
+
};
|
|
1283
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1284
|
+
exports.getUrl = void 0;
|
|
1285
|
+
var socket_io_1 = socketIo;
|
|
1286
|
+
var constants_1 = constants;
|
|
1287
|
+
var waitFor = function (duration) { return new Promise(function (resolve) { return window.setTimeout(resolve, duration); }); };
|
|
1288
|
+
var getUrl = function (url_1, optionsRef_1) {
|
|
1289
|
+
var args_1 = [];
|
|
1290
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
1291
|
+
args_1[_i - 2] = arguments[_i];
|
|
1292
|
+
}
|
|
1293
|
+
return __awaiter(void 0, __spreadArray([url_1, optionsRef_1], args_1, true), void 0, function (url, optionsRef, retriedAttempts) {
|
|
1294
|
+
var convertedUrl, reconnectLimit, nextReconnectInterval, parsedUrl, parsedWithQueryParams;
|
|
1295
|
+
var _a, _b, _c;
|
|
1296
|
+
if (retriedAttempts === void 0) { retriedAttempts = 0; }
|
|
1297
|
+
return __generator(this, function (_d) {
|
|
1298
|
+
switch (_d.label) {
|
|
1299
|
+
case 0:
|
|
1300
|
+
if (!(typeof url === 'function')) return [3 /*break*/, 10];
|
|
1301
|
+
_d.label = 1;
|
|
1302
|
+
case 1:
|
|
1303
|
+
_d.trys.push([1, 3, , 9]);
|
|
1304
|
+
return [4 /*yield*/, url()];
|
|
1305
|
+
case 2:
|
|
1306
|
+
convertedUrl = _d.sent();
|
|
1307
|
+
return [3 /*break*/, 9];
|
|
1308
|
+
case 3:
|
|
1309
|
+
_d.sent();
|
|
1310
|
+
if (!optionsRef.current.retryOnError) return [3 /*break*/, 7];
|
|
1311
|
+
reconnectLimit = (_a = optionsRef.current.reconnectAttempts) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_RECONNECT_LIMIT;
|
|
1312
|
+
if (!(retriedAttempts < reconnectLimit)) return [3 /*break*/, 5];
|
|
1313
|
+
nextReconnectInterval = typeof optionsRef.current.reconnectInterval === 'function' ?
|
|
1314
|
+
optionsRef.current.reconnectInterval(retriedAttempts) :
|
|
1315
|
+
optionsRef.current.reconnectInterval;
|
|
1316
|
+
return [4 /*yield*/, waitFor(nextReconnectInterval !== null && nextReconnectInterval !== void 0 ? nextReconnectInterval : constants_1.DEFAULT_RECONNECT_INTERVAL_MS)];
|
|
1317
|
+
case 4:
|
|
1318
|
+
_d.sent();
|
|
1319
|
+
return [2 /*return*/, (0, exports.getUrl)(url, optionsRef, retriedAttempts + 1)];
|
|
1320
|
+
case 5:
|
|
1321
|
+
(_c = (_b = optionsRef.current).onReconnectStop) === null || _c === void 0 ? void 0 : _c.call(_b, retriedAttempts);
|
|
1322
|
+
return [2 /*return*/, null];
|
|
1323
|
+
case 6: return [3 /*break*/, 8];
|
|
1324
|
+
case 7: return [2 /*return*/, null];
|
|
1325
|
+
case 8: return [3 /*break*/, 9];
|
|
1326
|
+
case 9: return [3 /*break*/, 11];
|
|
1327
|
+
case 10:
|
|
1328
|
+
convertedUrl = url;
|
|
1329
|
+
_d.label = 11;
|
|
1330
|
+
case 11:
|
|
1331
|
+
parsedUrl = optionsRef.current.fromSocketIO ?
|
|
1332
|
+
(0, socket_io_1.parseSocketIOUrl)(convertedUrl) :
|
|
1333
|
+
convertedUrl;
|
|
1334
|
+
parsedWithQueryParams = optionsRef.current.queryParams ?
|
|
1335
|
+
(0, socket_io_1.appendQueryParams)(parsedUrl, optionsRef.current.queryParams) :
|
|
1336
|
+
parsedUrl;
|
|
1337
|
+
return [2 /*return*/, parsedWithQueryParams];
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
});
|
|
1341
|
+
};
|
|
1342
|
+
exports.getUrl = getUrl;
|
|
1343
|
+
|
|
1344
|
+
} (getUrl));
|
|
1345
|
+
|
|
1346
|
+
var proxy = {};
|
|
1347
|
+
|
|
1348
|
+
(function (exports) {
|
|
1349
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1350
|
+
exports.websocketWrapper = void 0;
|
|
1351
|
+
var websocketWrapper = function (webSocket, start) {
|
|
1352
|
+
return new Proxy(webSocket, {
|
|
1353
|
+
get: function (obj, key) {
|
|
1354
|
+
var val = obj[key];
|
|
1355
|
+
if (key === 'reconnect')
|
|
1356
|
+
return start;
|
|
1357
|
+
if (typeof val === 'function') {
|
|
1358
|
+
console.error('Calling methods directly on the websocket is not supported at this moment. You must use the methods returned by useWebSocket.');
|
|
1359
|
+
//Prevent error thrown by invoking a non-function
|
|
1360
|
+
return function () { };
|
|
1361
|
+
}
|
|
1362
|
+
else {
|
|
1363
|
+
return val;
|
|
1364
|
+
}
|
|
1365
|
+
},
|
|
1366
|
+
set: function (obj, key, val) {
|
|
1367
|
+
if (/^on/.test(key)) {
|
|
1368
|
+
console.warn('The websocket\'s event handlers should be defined through the options object passed into useWebSocket.');
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
else {
|
|
1372
|
+
obj[key] = val;
|
|
1373
|
+
return true;
|
|
1374
|
+
}
|
|
1375
|
+
},
|
|
1376
|
+
});
|
|
1377
|
+
};
|
|
1378
|
+
exports.websocketWrapper = websocketWrapper;
|
|
1379
|
+
exports.default = exports.websocketWrapper;
|
|
1380
|
+
|
|
1381
|
+
} (proxy));
|
|
1382
|
+
|
|
1383
|
+
var __assign$2 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1384
|
+
__assign$2 = Object.assign || function(t) {
|
|
1385
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1386
|
+
s = arguments[i];
|
|
1387
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1388
|
+
t[p] = s[p];
|
|
1389
|
+
}
|
|
1390
|
+
return t;
|
|
1391
|
+
};
|
|
1392
|
+
return __assign$2.apply(this, arguments);
|
|
1393
|
+
};
|
|
1394
|
+
var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1395
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1396
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1397
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1398
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1399
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1400
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1401
|
+
});
|
|
1402
|
+
};
|
|
1403
|
+
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
|
|
1404
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
1405
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
1406
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
1407
|
+
function step(op) {
|
|
1408
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
1409
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
1410
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
1411
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
1412
|
+
switch (op[0]) {
|
|
1413
|
+
case 0: case 1: t = op; break;
|
|
1414
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
1415
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
1416
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
1417
|
+
default:
|
|
1418
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
1419
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
1420
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
1421
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
1422
|
+
if (t[2]) _.ops.pop();
|
|
1423
|
+
_.trys.pop(); continue;
|
|
1424
|
+
}
|
|
1425
|
+
op = body.call(thisArg, _);
|
|
1426
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
1427
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1430
|
+
var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
|
|
1431
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
1432
|
+
};
|
|
1433
|
+
Object.defineProperty(useWebsocket, "__esModule", { value: true });
|
|
1434
|
+
useWebsocket.useWebSocket = void 0;
|
|
1435
|
+
var react_1$2 = require$$0;
|
|
1436
|
+
var react_dom_1 = require$$1;
|
|
1437
|
+
var constants_1$2 = constants;
|
|
1438
|
+
var create_or_join_1 = createOrJoin;
|
|
1439
|
+
var get_url_1 = getUrl;
|
|
1440
|
+
var proxy_1 = __importDefault(proxy);
|
|
1441
|
+
var util_1 = util;
|
|
1442
|
+
var useWebSocket$1 = function (url, options, connect) {
|
|
1443
|
+
if (options === void 0) { options = constants_1$2.DEFAULT_OPTIONS; }
|
|
1444
|
+
if (connect === void 0) { connect = true; }
|
|
1445
|
+
var _a = (0, react_1$2.useState)(null), lastMessage = _a[0], setLastMessage = _a[1];
|
|
1446
|
+
var _b = (0, react_1$2.useState)({}), readyState = _b[0], setReadyState = _b[1];
|
|
1447
|
+
var lastJsonMessage = (0, react_1$2.useMemo)(function () {
|
|
1448
|
+
if (!options.disableJson && lastMessage) {
|
|
1449
|
+
try {
|
|
1450
|
+
return JSON.parse(lastMessage.data);
|
|
1451
|
+
}
|
|
1452
|
+
catch (e) {
|
|
1453
|
+
return constants_1$2.UNPARSABLE_JSON_OBJECT;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
return null;
|
|
1457
|
+
}, [lastMessage, options.disableJson]);
|
|
1458
|
+
var convertedUrl = (0, react_1$2.useRef)(null);
|
|
1459
|
+
var webSocketRef = (0, react_1$2.useRef)(null);
|
|
1460
|
+
var startRef = (0, react_1$2.useRef)(function () { return void 0; });
|
|
1461
|
+
var reconnectCount = (0, react_1$2.useRef)(0);
|
|
1462
|
+
var lastMessageTime = (0, react_1$2.useRef)(Date.now());
|
|
1463
|
+
var messageQueue = (0, react_1$2.useRef)([]);
|
|
1464
|
+
var webSocketProxy = (0, react_1$2.useRef)(null);
|
|
1465
|
+
var optionsCache = (0, react_1$2.useRef)(options);
|
|
1466
|
+
optionsCache.current = options;
|
|
1467
|
+
var readyStateFromUrl = convertedUrl.current && readyState[convertedUrl.current] !== undefined ?
|
|
1468
|
+
readyState[convertedUrl.current] :
|
|
1469
|
+
url !== null && connect === true ?
|
|
1470
|
+
constants_1$2.ReadyState.CONNECTING :
|
|
1471
|
+
constants_1$2.ReadyState.UNINSTANTIATED;
|
|
1472
|
+
var stringifiedQueryParams = options.queryParams ? JSON.stringify(options.queryParams) : null;
|
|
1473
|
+
var sendMessage = (0, react_1$2.useCallback)(function (message, keep) {
|
|
1474
|
+
var _a;
|
|
1475
|
+
if (keep === void 0) { keep = true; }
|
|
1476
|
+
if (constants_1$2.isEventSourceSupported && webSocketRef.current instanceof EventSource) {
|
|
1477
|
+
console.warn('Unable to send a message from an eventSource');
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
if (((_a = webSocketRef.current) === null || _a === void 0 ? void 0 : _a.readyState) === constants_1$2.ReadyState.OPEN) {
|
|
1481
|
+
(0, util_1.assertIsWebSocket)(webSocketRef.current, optionsCache.current.skipAssert);
|
|
1482
|
+
webSocketRef.current.send(message);
|
|
1483
|
+
}
|
|
1484
|
+
else if (keep) {
|
|
1485
|
+
messageQueue.current.push(message);
|
|
1486
|
+
}
|
|
1487
|
+
}, []);
|
|
1488
|
+
var sendJsonMessage = (0, react_1$2.useCallback)(function (message, keep) {
|
|
1489
|
+
if (keep === void 0) { keep = true; }
|
|
1490
|
+
sendMessage(JSON.stringify(message), keep);
|
|
1491
|
+
}, [sendMessage]);
|
|
1492
|
+
var getWebSocket = (0, react_1$2.useCallback)(function () {
|
|
1493
|
+
if (optionsCache.current.share !== true || (constants_1$2.isEventSourceSupported && webSocketRef.current instanceof EventSource)) {
|
|
1494
|
+
return webSocketRef.current;
|
|
1495
|
+
}
|
|
1496
|
+
if (webSocketProxy.current === null && webSocketRef.current) {
|
|
1497
|
+
(0, util_1.assertIsWebSocket)(webSocketRef.current, optionsCache.current.skipAssert);
|
|
1498
|
+
webSocketProxy.current = (0, proxy_1.default)(webSocketRef.current, startRef);
|
|
1499
|
+
}
|
|
1500
|
+
return webSocketProxy.current;
|
|
1501
|
+
}, []);
|
|
1502
|
+
(0, react_1$2.useEffect)(function () {
|
|
1503
|
+
if (url !== null && connect === true) {
|
|
1504
|
+
var removeListeners_1;
|
|
1505
|
+
var expectClose_1 = false;
|
|
1506
|
+
var createOrJoin_1 = true;
|
|
1507
|
+
var start_1 = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1508
|
+
var _a, protectedSetLastMessage, protectedSetReadyState;
|
|
1509
|
+
return __generator(this, function (_b) {
|
|
1510
|
+
switch (_b.label) {
|
|
1511
|
+
case 0:
|
|
1512
|
+
_a = convertedUrl;
|
|
1513
|
+
return [4 /*yield*/, (0, get_url_1.getUrl)(url, optionsCache)];
|
|
1514
|
+
case 1:
|
|
1515
|
+
_a.current = _b.sent();
|
|
1516
|
+
if (convertedUrl.current === null) {
|
|
1517
|
+
console.error('Failed to get a valid URL. WebSocket connection aborted.');
|
|
1518
|
+
convertedUrl.current = 'ABORTED';
|
|
1519
|
+
(0, react_dom_1.flushSync)(function () { return setReadyState(function (prev) { return (__assign$2(__assign$2({}, prev), { ABORTED: constants_1$2.ReadyState.CLOSED })); }); });
|
|
1520
|
+
return [2 /*return*/];
|
|
1521
|
+
}
|
|
1522
|
+
protectedSetLastMessage = function (message) {
|
|
1523
|
+
if (!expectClose_1) {
|
|
1524
|
+
(0, react_dom_1.flushSync)(function () { return setLastMessage(message); });
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
protectedSetReadyState = function (state) {
|
|
1528
|
+
if (!expectClose_1) {
|
|
1529
|
+
(0, react_dom_1.flushSync)(function () { return setReadyState(function (prev) {
|
|
1530
|
+
var _a;
|
|
1531
|
+
return (__assign$2(__assign$2({}, prev), (convertedUrl.current && (_a = {}, _a[convertedUrl.current] = state, _a))));
|
|
1532
|
+
}); });
|
|
1533
|
+
}
|
|
1534
|
+
};
|
|
1535
|
+
if (createOrJoin_1) {
|
|
1536
|
+
removeListeners_1 = (0, create_or_join_1.createOrJoinSocket)(webSocketRef, convertedUrl.current, protectedSetReadyState, optionsCache, protectedSetLastMessage, startRef, reconnectCount, lastMessageTime, sendMessage);
|
|
1537
|
+
}
|
|
1538
|
+
return [2 /*return*/];
|
|
1539
|
+
}
|
|
1540
|
+
});
|
|
1541
|
+
}); };
|
|
1542
|
+
startRef.current = function () {
|
|
1543
|
+
if (!expectClose_1) {
|
|
1544
|
+
if (webSocketProxy.current)
|
|
1545
|
+
webSocketProxy.current = null;
|
|
1546
|
+
removeListeners_1 === null || removeListeners_1 === void 0 ? void 0 : removeListeners_1();
|
|
1547
|
+
start_1();
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
start_1();
|
|
1551
|
+
return function () {
|
|
1552
|
+
expectClose_1 = true;
|
|
1553
|
+
createOrJoin_1 = false;
|
|
1554
|
+
if (webSocketProxy.current)
|
|
1555
|
+
webSocketProxy.current = null;
|
|
1556
|
+
removeListeners_1 === null || removeListeners_1 === void 0 ? void 0 : removeListeners_1();
|
|
1557
|
+
setLastMessage(null);
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
else if (url === null || connect === false) {
|
|
1561
|
+
reconnectCount.current = 0; // reset reconnection attempts
|
|
1562
|
+
setReadyState(function (prev) {
|
|
1563
|
+
var _a;
|
|
1564
|
+
return (__assign$2(__assign$2({}, prev), (convertedUrl.current && (_a = {}, _a[convertedUrl.current] = constants_1$2.ReadyState.CLOSED, _a))));
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
}, [url, connect, stringifiedQueryParams, sendMessage]);
|
|
1568
|
+
(0, react_1$2.useEffect)(function () {
|
|
1569
|
+
if (readyStateFromUrl === constants_1$2.ReadyState.OPEN) {
|
|
1570
|
+
messageQueue.current.splice(0).forEach(function (message) {
|
|
1571
|
+
sendMessage(message);
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
}, [readyStateFromUrl]);
|
|
1575
|
+
return {
|
|
1576
|
+
sendMessage: sendMessage,
|
|
1577
|
+
sendJsonMessage: sendJsonMessage,
|
|
1578
|
+
lastMessage: lastMessage,
|
|
1579
|
+
lastJsonMessage: lastJsonMessage,
|
|
1580
|
+
readyState: readyStateFromUrl,
|
|
1581
|
+
getWebSocket: getWebSocket,
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
useWebsocket.useWebSocket = useWebSocket$1;
|
|
1585
|
+
|
|
1586
|
+
var useSocketIo = {};
|
|
1587
|
+
|
|
1588
|
+
var __assign$1 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1589
|
+
__assign$1 = Object.assign || function(t) {
|
|
1590
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1591
|
+
s = arguments[i];
|
|
1592
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1593
|
+
t[p] = s[p];
|
|
1594
|
+
}
|
|
1595
|
+
return t;
|
|
1596
|
+
};
|
|
1597
|
+
return __assign$1.apply(this, arguments);
|
|
1598
|
+
};
|
|
1599
|
+
Object.defineProperty(useSocketIo, "__esModule", { value: true });
|
|
1600
|
+
useSocketIo.useSocketIO = void 0;
|
|
1601
|
+
var react_1$1 = require$$0;
|
|
1602
|
+
var use_websocket_1$1 = useWebsocket;
|
|
1603
|
+
var constants_1$1 = constants;
|
|
1604
|
+
var emptyEvent = {
|
|
1605
|
+
type: 'empty',
|
|
1606
|
+
payload: null,
|
|
1607
|
+
};
|
|
1608
|
+
var getSocketData = function (event) {
|
|
1609
|
+
if (!event || !event.data) {
|
|
1610
|
+
return emptyEvent;
|
|
1611
|
+
}
|
|
1612
|
+
var match = event.data.match(/\[.*]/);
|
|
1613
|
+
if (!match) {
|
|
1614
|
+
return emptyEvent;
|
|
1615
|
+
}
|
|
1616
|
+
var data = JSON.parse(match);
|
|
1617
|
+
if (!Array.isArray(data) || !data[1]) {
|
|
1618
|
+
return emptyEvent;
|
|
1619
|
+
}
|
|
1620
|
+
return {
|
|
1621
|
+
type: data[0],
|
|
1622
|
+
payload: data[1],
|
|
1623
|
+
};
|
|
1624
|
+
};
|
|
1625
|
+
var useSocketIO = function (url, options, connect) {
|
|
1626
|
+
if (options === void 0) { options = constants_1$1.DEFAULT_OPTIONS; }
|
|
1627
|
+
if (connect === void 0) { connect = true; }
|
|
1628
|
+
var optionsWithSocketIO = (0, react_1$1.useMemo)(function () { return (__assign$1(__assign$1({}, options), { fromSocketIO: true })); }, []);
|
|
1629
|
+
var _a = (0, use_websocket_1$1.useWebSocket)(url, optionsWithSocketIO, connect), sendMessage = _a.sendMessage, sendJsonMessage = _a.sendJsonMessage, lastMessage = _a.lastMessage, readyState = _a.readyState, getWebSocket = _a.getWebSocket;
|
|
1630
|
+
var socketIOLastMessage = (0, react_1$1.useMemo)(function () {
|
|
1631
|
+
return getSocketData(lastMessage);
|
|
1632
|
+
}, [lastMessage]);
|
|
1633
|
+
return {
|
|
1634
|
+
sendMessage: sendMessage,
|
|
1635
|
+
sendJsonMessage: sendJsonMessage,
|
|
1636
|
+
lastMessage: socketIOLastMessage,
|
|
1637
|
+
lastJsonMessage: socketIOLastMessage,
|
|
1638
|
+
readyState: readyState,
|
|
1639
|
+
getWebSocket: getWebSocket,
|
|
1640
|
+
};
|
|
1641
|
+
};
|
|
1642
|
+
useSocketIo.useSocketIO = useSocketIO;
|
|
1643
|
+
|
|
1644
|
+
var useEventSource$1 = {};
|
|
1645
|
+
|
|
1646
|
+
var __assign = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1647
|
+
__assign = Object.assign || function(t) {
|
|
1648
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1649
|
+
s = arguments[i];
|
|
1650
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1651
|
+
t[p] = s[p];
|
|
1652
|
+
}
|
|
1653
|
+
return t;
|
|
1654
|
+
};
|
|
1655
|
+
return __assign.apply(this, arguments);
|
|
1656
|
+
};
|
|
1657
|
+
var __rest = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) {
|
|
1658
|
+
var t = {};
|
|
1659
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
1660
|
+
t[p] = s[p];
|
|
1661
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
1662
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
1663
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
1664
|
+
t[p[i]] = s[p[i]];
|
|
1665
|
+
}
|
|
1666
|
+
return t;
|
|
1667
|
+
};
|
|
1668
|
+
Object.defineProperty(useEventSource$1, "__esModule", { value: true });
|
|
1669
|
+
useEventSource$1.useEventSource = void 0;
|
|
1670
|
+
var react_1 = require$$0;
|
|
1671
|
+
var use_websocket_1 = useWebsocket;
|
|
1672
|
+
var constants_1 = constants;
|
|
1673
|
+
var useEventSource = function (url, _a, connect) {
|
|
1674
|
+
if (_a === void 0) { _a = constants_1.DEFAULT_EVENT_SOURCE_OPTIONS; }
|
|
1675
|
+
var withCredentials = _a.withCredentials, events = _a.events, options = __rest(_a, ["withCredentials", "events"]);
|
|
1676
|
+
if (connect === void 0) { connect = true; }
|
|
1677
|
+
var optionsWithEventSource = __assign(__assign({}, options), { eventSourceOptions: {
|
|
1678
|
+
withCredentials: withCredentials,
|
|
1679
|
+
} });
|
|
1680
|
+
var eventsRef = (0, react_1.useRef)(constants_1.EMPTY_EVENT_HANDLERS);
|
|
1681
|
+
if (events) {
|
|
1682
|
+
eventsRef.current = events;
|
|
1683
|
+
}
|
|
1684
|
+
var _b = (0, use_websocket_1.useWebSocket)(url, optionsWithEventSource, connect), lastMessage = _b.lastMessage, readyState = _b.readyState, getWebSocket = _b.getWebSocket;
|
|
1685
|
+
(0, react_1.useEffect)(function () {
|
|
1686
|
+
if (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.type) {
|
|
1687
|
+
Object.entries(eventsRef.current).forEach(function (_a) {
|
|
1688
|
+
var type = _a[0], handler = _a[1];
|
|
1689
|
+
if (type === lastMessage.type) {
|
|
1690
|
+
handler(lastMessage);
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
}, [lastMessage]);
|
|
1695
|
+
return {
|
|
1696
|
+
lastEvent: lastMessage,
|
|
1697
|
+
readyState: readyState,
|
|
1698
|
+
getEventSource: getWebSocket,
|
|
1699
|
+
};
|
|
1700
|
+
};
|
|
1701
|
+
useEventSource$1.useEventSource = useEventSource;
|
|
1702
|
+
|
|
1703
|
+
(function (exports) {
|
|
1704
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1705
|
+
exports.resetGlobalState = exports.useEventSource = exports.ReadyState = exports.useSocketIO = exports.default = void 0;
|
|
1706
|
+
var use_websocket_1 = useWebsocket;
|
|
1707
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return use_websocket_1.useWebSocket; } });
|
|
1708
|
+
var use_socket_io_1 = useSocketIo;
|
|
1709
|
+
Object.defineProperty(exports, "useSocketIO", { enumerable: true, get: function () { return use_socket_io_1.useSocketIO; } });
|
|
1710
|
+
var constants_1 = constants;
|
|
1711
|
+
Object.defineProperty(exports, "ReadyState", { enumerable: true, get: function () { return constants_1.ReadyState; } });
|
|
1712
|
+
var use_event_source_1 = useEventSource$1;
|
|
1713
|
+
Object.defineProperty(exports, "useEventSource", { enumerable: true, get: function () { return use_event_source_1.useEventSource; } });
|
|
1714
|
+
var util_1 = util;
|
|
1715
|
+
Object.defineProperty(exports, "resetGlobalState", { enumerable: true, get: function () { return util_1.resetGlobalState; } });
|
|
1716
|
+
|
|
1717
|
+
} (dist));
|
|
1718
|
+
|
|
1719
|
+
var useWebSocket = /*@__PURE__*/getDefaultExportFromCjs(dist);
|
|
1720
|
+
|
|
1721
|
+
const useUserData = create((set) => ({
|
|
1722
|
+
tradeHistories: null,
|
|
1723
|
+
rawOpenPositions: null,
|
|
1724
|
+
openOrders: null,
|
|
1725
|
+
accountSummary: null,
|
|
1726
|
+
setTradeHistories: (value) => set({ tradeHistories: value }),
|
|
1727
|
+
setRawOpenPositions: (value) => set({ rawOpenPositions: value }),
|
|
1728
|
+
setOpenOrders: (value) => set({ openOrders: value }),
|
|
1729
|
+
setAccountSummary: (value) => set({ accountSummary: value }),
|
|
1730
|
+
clean: () => set({
|
|
1731
|
+
tradeHistories: null,
|
|
1732
|
+
rawOpenPositions: null,
|
|
1733
|
+
openOrders: null,
|
|
1734
|
+
accountSummary: null,
|
|
1735
|
+
}),
|
|
1736
|
+
}));
|
|
1737
|
+
|
|
1738
|
+
const useHyperliquidWebSocket = ({ wsUrl, address }) => {
|
|
1739
|
+
const { setTradeHistories, setRawOpenPositions, setOpenOrders, setAccountSummary, clean } = useUserData();
|
|
1740
|
+
const [lastError, setLastError] = useState(null);
|
|
1741
|
+
const [lastSubscribedAddress, setLastSubscribedAddress] = useState(null);
|
|
1742
|
+
// WebSocket connection
|
|
1743
|
+
const { readyState, sendMessage } = useWebSocket(wsUrl, {
|
|
1744
|
+
shouldReconnect: () => true,
|
|
1745
|
+
reconnectAttempts: 5,
|
|
1746
|
+
reconnectInterval: 3000,
|
|
1747
|
+
onMessage: (event) => {
|
|
1748
|
+
try {
|
|
1749
|
+
const message = JSON.parse(event.data);
|
|
1750
|
+
// Handle subscription responses (only if they don't have channel data)
|
|
1751
|
+
if (('success' in message || 'error' in message) && !('channel' in message)) {
|
|
1752
|
+
if (message.error) {
|
|
1753
|
+
setLastError(message.error);
|
|
1754
|
+
}
|
|
1755
|
+
else {
|
|
1756
|
+
setLastError(null);
|
|
1757
|
+
}
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
// Handle channel data messages
|
|
1761
|
+
if ('channel' in message && 'data' in message) {
|
|
1762
|
+
const dataMessage = message;
|
|
1763
|
+
// Validate data exists and is not null/undefined
|
|
1764
|
+
if (dataMessage.data === null || dataMessage.data === undefined) {
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
switch (dataMessage.channel) {
|
|
1768
|
+
case 'trade-histories':
|
|
1769
|
+
setTradeHistories(dataMessage.data);
|
|
1770
|
+
break;
|
|
1771
|
+
case 'open-positions':
|
|
1772
|
+
setRawOpenPositions(dataMessage.data);
|
|
1773
|
+
break;
|
|
1774
|
+
case 'open-orders':
|
|
1775
|
+
setOpenOrders(dataMessage.data);
|
|
1776
|
+
break;
|
|
1777
|
+
case 'account-summary':
|
|
1778
|
+
setAccountSummary(dataMessage.data);
|
|
1779
|
+
break;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
catch (error) {
|
|
1784
|
+
setLastError(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
});
|
|
1788
|
+
const isConnected = readyState === dist.ReadyState.OPEN;
|
|
1789
|
+
// Handle subscription management
|
|
1790
|
+
useEffect(() => {
|
|
1791
|
+
if (isConnected && address && address !== lastSubscribedAddress) {
|
|
1792
|
+
// Unsubscribe from previous address if exists
|
|
1793
|
+
if (lastSubscribedAddress) {
|
|
1794
|
+
sendMessage(JSON.stringify({
|
|
1795
|
+
action: 'unsubscribe',
|
|
1796
|
+
address: lastSubscribedAddress
|
|
1797
|
+
}));
|
|
1798
|
+
}
|
|
1799
|
+
// Subscribe to new address
|
|
1800
|
+
sendMessage(JSON.stringify({
|
|
1801
|
+
action: 'subscribe',
|
|
1802
|
+
address: address
|
|
1803
|
+
}));
|
|
1804
|
+
setLastSubscribedAddress(address);
|
|
1805
|
+
setLastError(null);
|
|
1806
|
+
}
|
|
1807
|
+
else if (isConnected && !address && lastSubscribedAddress) {
|
|
1808
|
+
// Send unsubscribe action when address is removed
|
|
1809
|
+
sendMessage(JSON.stringify({
|
|
1810
|
+
action: 'unsubscribe',
|
|
1811
|
+
address: lastSubscribedAddress
|
|
1812
|
+
}));
|
|
1813
|
+
setLastSubscribedAddress(null);
|
|
1814
|
+
}
|
|
1815
|
+
}, [isConnected, address, lastSubscribedAddress, sendMessage]);
|
|
1816
|
+
// Clear data when address changes
|
|
1817
|
+
useEffect(() => {
|
|
1818
|
+
if (address !== lastSubscribedAddress) {
|
|
1819
|
+
clean();
|
|
1820
|
+
setLastError(null);
|
|
1821
|
+
}
|
|
1822
|
+
}, [address, lastSubscribedAddress]);
|
|
1823
|
+
return {
|
|
1824
|
+
connectionStatus: readyState,
|
|
1825
|
+
isConnected,
|
|
1826
|
+
lastError,
|
|
1827
|
+
};
|
|
1828
|
+
};
|
|
1829
|
+
|
|
1830
|
+
const useHyperliquidData = create((set, get) => ({
|
|
1831
|
+
webData2: null,
|
|
1832
|
+
allMids: null,
|
|
1833
|
+
activeAssetData: null,
|
|
1834
|
+
candleData: null,
|
|
1835
|
+
setWebData2: (value) => set({ webData2: value }),
|
|
1836
|
+
setAllMids: (value) => set({ allMids: value }),
|
|
1837
|
+
setActiveAssetData: (value) => set((state) => ({
|
|
1838
|
+
activeAssetData: typeof value === 'function' ? value(state.activeAssetData) : value
|
|
1839
|
+
})),
|
|
1840
|
+
deleteActiveAssetData: (key) => {
|
|
1841
|
+
set((state) => {
|
|
1842
|
+
if (!state.activeAssetData || !(key in state.activeAssetData)) {
|
|
1843
|
+
return state; // No change if key doesn't exist
|
|
1844
|
+
}
|
|
1845
|
+
const updated = { ...state.activeAssetData };
|
|
1846
|
+
delete updated[key];
|
|
1847
|
+
return { activeAssetData: updated };
|
|
1848
|
+
});
|
|
1849
|
+
},
|
|
1850
|
+
addCandleData(symbol, candle) {
|
|
1851
|
+
set((state) => {
|
|
1852
|
+
return {
|
|
1853
|
+
candleData: {
|
|
1854
|
+
...state.candleData,
|
|
1855
|
+
[symbol]: candle
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
});
|
|
1859
|
+
},
|
|
1860
|
+
deleteCandleSymbol(symbol) {
|
|
1861
|
+
set((state) => {
|
|
1862
|
+
if (!state.candleData || !(symbol in state.candleData)) {
|
|
1863
|
+
return state; // No change if symbol doesn't exist
|
|
1864
|
+
}
|
|
1865
|
+
const updated = { ...state.candleData };
|
|
1866
|
+
delete updated[symbol];
|
|
1867
|
+
return { candleData: updated };
|
|
1868
|
+
});
|
|
1869
|
+
},
|
|
1870
|
+
setCandleData: (value) => set({ candleData: value }),
|
|
1871
|
+
upsertActiveAssetData: (key, value) => set((state) => ({
|
|
1872
|
+
activeAssetData: {
|
|
1873
|
+
...state.activeAssetData,
|
|
1874
|
+
[key]: value,
|
|
1875
|
+
}
|
|
1876
|
+
}))
|
|
1877
|
+
}));
|
|
1878
|
+
|
|
1879
|
+
const useHyperliquidNativeWebSocket = ({ address, tokens = [], candleInterval = "1h" }) => {
|
|
1880
|
+
const { setWebData2, setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData } = useHyperliquidData();
|
|
1881
|
+
const [lastError, setLastError] = useState(null);
|
|
1882
|
+
const [subscribedAddress, setSubscribedAddress] = useState(null);
|
|
1883
|
+
const [subscribedTokens, setSubscribedTokens] = useState([]);
|
|
1884
|
+
const [subscribedCandleTokens, setSubscribedCandleTokens] = useState([]);
|
|
1885
|
+
const [subscribedCandleInterval, setSubscribedCandleInterval] = useState(null);
|
|
1886
|
+
const pingIntervalRef = useRef(null);
|
|
1887
|
+
const { readyState, sendJsonMessage } = useWebSocket('wss://api.hyperliquid.xyz/ws', {
|
|
1888
|
+
shouldReconnect: () => true,
|
|
1889
|
+
reconnectAttempts: 5,
|
|
1890
|
+
reconnectInterval: 3000,
|
|
1891
|
+
onOpen: () => { },
|
|
1892
|
+
onClose: () => { },
|
|
1893
|
+
onError: (event) => console.error('[HyperLiquid WS] Connection error:', event),
|
|
1894
|
+
onReconnectStop: () => console.error('[HyperLiquid WS] Reconnection stopped after 5 attempts'),
|
|
1895
|
+
onMessage: (event) => {
|
|
1896
|
+
try {
|
|
1897
|
+
const message = JSON.parse(event.data);
|
|
1898
|
+
// Handle subscription responses
|
|
1899
|
+
if ('success' in message || 'error' in message) {
|
|
1900
|
+
if (message.error) {
|
|
1901
|
+
console.error('[HyperLiquid WS] Subscription error:', message.error);
|
|
1902
|
+
setLastError(message.error);
|
|
1903
|
+
}
|
|
1904
|
+
else {
|
|
1905
|
+
setLastError(null);
|
|
1906
|
+
}
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
// Handle channel data messages
|
|
1910
|
+
if ('channel' in message && 'data' in message) {
|
|
1911
|
+
const response = message;
|
|
1912
|
+
switch (response.channel) {
|
|
1913
|
+
case 'webData2':
|
|
1914
|
+
setWebData2(response.data);
|
|
1915
|
+
break;
|
|
1916
|
+
case 'allMids':
|
|
1917
|
+
setAllMids(response.data);
|
|
1918
|
+
break;
|
|
1919
|
+
case 'activeAssetData':
|
|
1920
|
+
const assetData = response.data;
|
|
1921
|
+
upsertActiveAssetData(assetData.coin, assetData);
|
|
1922
|
+
break;
|
|
1923
|
+
case 'candle':
|
|
1924
|
+
const candleDataItem = response.data;
|
|
1925
|
+
addCandleData(candleDataItem.c, candleDataItem);
|
|
1926
|
+
break;
|
|
1927
|
+
default:
|
|
1928
|
+
console.warn(`[HyperLiquid WS] Unknown channel: ${response.channel}`);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
catch (error) {
|
|
1933
|
+
const errorMessage = `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`;
|
|
1934
|
+
console.error('[HyperLiquid WS] Parse error:', errorMessage, 'Raw message:', event.data);
|
|
1935
|
+
setLastError(errorMessage);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
});
|
|
1939
|
+
const isConnected = readyState === dist.ReadyState.OPEN;
|
|
1940
|
+
// Setup ping mechanism
|
|
1941
|
+
useEffect(() => {
|
|
1942
|
+
if (isConnected) {
|
|
1943
|
+
// Send ping every 30 seconds
|
|
1944
|
+
pingIntervalRef.current = setInterval(() => {
|
|
1945
|
+
sendJsonMessage({ method: 'ping' });
|
|
1946
|
+
}, 30000);
|
|
1947
|
+
}
|
|
1948
|
+
else {
|
|
1949
|
+
if (pingIntervalRef.current) {
|
|
1950
|
+
clearInterval(pingIntervalRef.current);
|
|
1951
|
+
pingIntervalRef.current = null;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
return () => {
|
|
1955
|
+
if (pingIntervalRef.current) {
|
|
1956
|
+
clearInterval(pingIntervalRef.current);
|
|
1957
|
+
pingIntervalRef.current = null;
|
|
1958
|
+
}
|
|
1959
|
+
};
|
|
1960
|
+
}, [isConnected, sendJsonMessage]);
|
|
1961
|
+
// Handle address subscription changes
|
|
1962
|
+
useEffect(() => {
|
|
1963
|
+
if (!isConnected)
|
|
1964
|
+
return;
|
|
1965
|
+
const DEFAULT_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
1966
|
+
const userAddress = address || DEFAULT_ADDRESS;
|
|
1967
|
+
if (subscribedAddress === userAddress)
|
|
1968
|
+
return;
|
|
1969
|
+
// Unsubscribe from previous address if exists
|
|
1970
|
+
if (subscribedAddress) {
|
|
1971
|
+
const unsubscribeMessage = {
|
|
1972
|
+
method: 'unsubscribe',
|
|
1973
|
+
subscription: {
|
|
1974
|
+
type: 'webData2',
|
|
1975
|
+
user: subscribedAddress,
|
|
1976
|
+
},
|
|
1977
|
+
};
|
|
1978
|
+
sendJsonMessage(unsubscribeMessage);
|
|
1979
|
+
}
|
|
1980
|
+
// Subscribe to webData2 with new address
|
|
1981
|
+
const subscribeWebData2 = {
|
|
1982
|
+
method: 'subscribe',
|
|
1983
|
+
subscription: {
|
|
1984
|
+
type: 'webData2',
|
|
1985
|
+
user: userAddress,
|
|
1986
|
+
},
|
|
1987
|
+
};
|
|
1988
|
+
// Subscribe to allMids
|
|
1989
|
+
const subscribeAllMids = {
|
|
1990
|
+
method: 'subscribe',
|
|
1991
|
+
subscription: {
|
|
1992
|
+
type: 'allMids',
|
|
1993
|
+
},
|
|
1994
|
+
};
|
|
1995
|
+
sendJsonMessage(subscribeWebData2);
|
|
1996
|
+
sendJsonMessage(subscribeAllMids);
|
|
1997
|
+
setSubscribedAddress(userAddress);
|
|
1998
|
+
// Clear previous data when address changes
|
|
1999
|
+
if (subscribedAddress && subscribedAddress !== userAddress) {
|
|
2000
|
+
setWebData2(null);
|
|
2001
|
+
}
|
|
2002
|
+
}, [isConnected, address, subscribedAddress, sendJsonMessage, setWebData2]);
|
|
2003
|
+
// Handle token subscriptions for activeAssetData
|
|
2004
|
+
useEffect(() => {
|
|
2005
|
+
if (!isConnected || !address)
|
|
2006
|
+
return;
|
|
2007
|
+
const tokensToSubscribe = tokens.filter(token => token && !subscribedTokens.includes(token));
|
|
2008
|
+
const tokensToUnsubscribe = subscribedTokens.filter(token => !tokens.includes(token));
|
|
2009
|
+
// Unsubscribe from tokens no longer in the list
|
|
2010
|
+
tokensToUnsubscribe.forEach(token => {
|
|
2011
|
+
const unsubscribeMessage = {
|
|
2012
|
+
method: 'unsubscribe',
|
|
2013
|
+
subscription: {
|
|
2014
|
+
type: 'activeAssetData',
|
|
2015
|
+
user: address,
|
|
2016
|
+
coin: token,
|
|
2017
|
+
},
|
|
2018
|
+
};
|
|
2019
|
+
sendJsonMessage(unsubscribeMessage);
|
|
2020
|
+
});
|
|
2021
|
+
// Subscribe to new tokens
|
|
2022
|
+
tokensToSubscribe.forEach(token => {
|
|
2023
|
+
const subscribeMessage = {
|
|
2024
|
+
method: 'subscribe',
|
|
2025
|
+
subscription: {
|
|
2026
|
+
type: 'activeAssetData',
|
|
2027
|
+
user: address,
|
|
2028
|
+
coin: token,
|
|
2029
|
+
},
|
|
2030
|
+
};
|
|
2031
|
+
sendJsonMessage(subscribeMessage);
|
|
2032
|
+
});
|
|
2033
|
+
if (tokensToSubscribe.length > 0 || tokensToUnsubscribe.length > 0) {
|
|
2034
|
+
setSubscribedTokens(tokens.filter(token => token));
|
|
2035
|
+
tokensToSubscribe.forEach(token => deleteActiveAssetData(token));
|
|
2036
|
+
}
|
|
2037
|
+
}, [isConnected, address, tokens, subscribedTokens, sendJsonMessage, setActiveAssetData]);
|
|
2038
|
+
// Handle candle subscriptions for tokens and interval changes
|
|
2039
|
+
useEffect(() => {
|
|
2040
|
+
if (!isConnected)
|
|
2041
|
+
return;
|
|
2042
|
+
// Unsubscribe from previous candle subscriptions if interval changed
|
|
2043
|
+
if (subscribedCandleInterval && subscribedCandleInterval !== candleInterval) {
|
|
2044
|
+
subscribedCandleTokens.forEach(token => {
|
|
2045
|
+
const unsubscribeMessage = {
|
|
2046
|
+
method: 'unsubscribe',
|
|
2047
|
+
subscription: {
|
|
2048
|
+
type: 'candle',
|
|
2049
|
+
coin: token,
|
|
2050
|
+
interval: subscribedCandleInterval,
|
|
2051
|
+
},
|
|
2052
|
+
};
|
|
2053
|
+
sendJsonMessage(unsubscribeMessage);
|
|
2054
|
+
});
|
|
2055
|
+
setCandleData({});
|
|
2056
|
+
setSubscribedCandleTokens([]);
|
|
2057
|
+
}
|
|
2058
|
+
const tokensToSubscribe = tokens.filter(token => token && !subscribedCandleTokens.includes(token));
|
|
2059
|
+
const tokensToUnsubscribe = subscribedCandleTokens.filter(token => !tokens.includes(token));
|
|
2060
|
+
// Unsubscribe from tokens no longer in the list
|
|
2061
|
+
tokensToUnsubscribe.forEach(token => {
|
|
2062
|
+
const unsubscribeMessage = {
|
|
2063
|
+
method: 'unsubscribe',
|
|
2064
|
+
subscription: {
|
|
2065
|
+
type: 'candle',
|
|
2066
|
+
coin: token,
|
|
2067
|
+
interval: candleInterval,
|
|
2068
|
+
},
|
|
2069
|
+
};
|
|
2070
|
+
sendJsonMessage(unsubscribeMessage);
|
|
2071
|
+
});
|
|
2072
|
+
// Subscribe to new tokens
|
|
2073
|
+
tokensToSubscribe.forEach(token => {
|
|
2074
|
+
const subscribeMessage = {
|
|
2075
|
+
method: 'subscribe',
|
|
2076
|
+
subscription: {
|
|
2077
|
+
type: 'candle',
|
|
2078
|
+
coin: token,
|
|
2079
|
+
interval: candleInterval,
|
|
2080
|
+
},
|
|
2081
|
+
};
|
|
2082
|
+
sendJsonMessage(subscribeMessage);
|
|
2083
|
+
});
|
|
2084
|
+
// Update subscribed state
|
|
2085
|
+
if (tokensToSubscribe.length > 0 || tokensToUnsubscribe.length > 0 || subscribedCandleInterval !== candleInterval) {
|
|
2086
|
+
setSubscribedCandleTokens(tokens.filter(token => token));
|
|
2087
|
+
setSubscribedCandleInterval(candleInterval);
|
|
2088
|
+
tokensToUnsubscribe.forEach(token => deleteCandleSymbol(token));
|
|
2089
|
+
}
|
|
2090
|
+
}, [isConnected, tokens, candleInterval, subscribedCandleTokens, subscribedCandleInterval, sendJsonMessage, setCandleData]);
|
|
2091
|
+
return {
|
|
2092
|
+
connectionStatus: readyState,
|
|
2093
|
+
isConnected,
|
|
2094
|
+
lastError,
|
|
2095
|
+
};
|
|
2096
|
+
};
|
|
2097
|
+
|
|
2098
|
+
const PearHyperliquidContext = createContext(undefined);
|
|
2099
|
+
/**
|
|
2100
|
+
* React Provider for PearHyperliquidClient
|
|
2101
|
+
*/
|
|
2102
|
+
const PearHyperliquidProvider = ({ config, wsUrl = 'wss://hl-v2.pearprotocol.io/ws', children, }) => {
|
|
2103
|
+
const client = useMemo(() => new PearHyperliquidClient(config), [config]);
|
|
2104
|
+
const migrationSDK = useMemo(() => new PearMigrationSDK(client), [client]);
|
|
2105
|
+
const [address, setAddress] = useState(null);
|
|
2106
|
+
// WebSocket connection and data (Pear API)
|
|
2107
|
+
const { connectionStatus, isConnected, lastError } = useHyperliquidWebSocket({
|
|
2108
|
+
wsUrl,
|
|
2109
|
+
address,
|
|
2110
|
+
});
|
|
2111
|
+
// HyperLiquid native WebSocket connection
|
|
2112
|
+
const { connectionStatus: nativeConnectionStatus, isConnected: nativeIsConnected, lastError: nativeLastError } = useHyperliquidNativeWebSocket({
|
|
2113
|
+
address,
|
|
2114
|
+
});
|
|
2115
|
+
const contextValue = useMemo(() => ({
|
|
2116
|
+
// Existing clients
|
|
2117
|
+
client,
|
|
2118
|
+
migrationSDK,
|
|
2119
|
+
// Address management
|
|
2120
|
+
address,
|
|
2121
|
+
setAddress,
|
|
2122
|
+
// WebSocket state (Pear API)
|
|
2123
|
+
connectionStatus,
|
|
2124
|
+
isConnected,
|
|
2125
|
+
// WebSocket data (Pear API)
|
|
2126
|
+
lastError,
|
|
2127
|
+
// HyperLiquid native WebSocket state
|
|
2128
|
+
nativeConnectionStatus,
|
|
2129
|
+
nativeIsConnected,
|
|
2130
|
+
nativeLastError,
|
|
2131
|
+
}), [client, migrationSDK, address, connectionStatus, isConnected, lastError, nativeConnectionStatus, nativeIsConnected, nativeLastError]);
|
|
2132
|
+
return (jsxRuntimeExports.jsx(PearHyperliquidContext.Provider, { value: contextValue, children: children }));
|
|
2133
|
+
};
|
|
2134
|
+
/**
|
|
2135
|
+
* Hook to use PearHyperliquidClient from context
|
|
2136
|
+
*/
|
|
2137
|
+
const usePearHyperliquidClient = () => {
|
|
2138
|
+
const context = useContext(PearHyperliquidContext);
|
|
2139
|
+
if (!context) {
|
|
2140
|
+
throw new Error('usePearHyperliquidClient must be used within a PearHyperliquidProvider');
|
|
2141
|
+
}
|
|
2142
|
+
return context.client;
|
|
2143
|
+
};
|
|
2144
|
+
/**
|
|
2145
|
+
* Hook to use migration SDK from context
|
|
2146
|
+
*/
|
|
2147
|
+
const useMigrationSDK = () => {
|
|
2148
|
+
const context = useContext(PearHyperliquidContext);
|
|
2149
|
+
if (!context) {
|
|
2150
|
+
throw new Error('useMigrationSDK must be used within a PearHyperliquidProvider');
|
|
2151
|
+
}
|
|
2152
|
+
return context.migrationSDK;
|
|
2153
|
+
};
|
|
2154
|
+
|
|
2155
|
+
/**
|
|
2156
|
+
* Hook to manage address (login/logout functionality)
|
|
2157
|
+
*/
|
|
2158
|
+
const useAddress = () => {
|
|
2159
|
+
const context = useContext(PearHyperliquidContext);
|
|
2160
|
+
if (!context) {
|
|
2161
|
+
throw new Error('useAddress must be used within a PearHyperliquidProvider');
|
|
2162
|
+
}
|
|
2163
|
+
return {
|
|
2164
|
+
address: context.address,
|
|
2165
|
+
setAddress: context.setAddress,
|
|
2166
|
+
clearAddress: () => context.setAddress(null),
|
|
2167
|
+
isLoggedIn: !!context.address,
|
|
2168
|
+
};
|
|
2169
|
+
};
|
|
2170
|
+
|
|
2171
|
+
/**
|
|
2172
|
+
* Account summary calculation utility class
|
|
2173
|
+
*/
|
|
2174
|
+
class AccountSummaryCalculator {
|
|
2175
|
+
constructor(webData2) {
|
|
2176
|
+
this.webData2 = webData2;
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* Calculate account summary from webData2 and platform orders
|
|
2180
|
+
*/
|
|
2181
|
+
calculateAccountSummary(platformAccountSummary, platformOpenOrders, agentWalletAddress, agentWalletStatus) {
|
|
2182
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2183
|
+
// If we don't have webData2, return platform data as-is
|
|
2184
|
+
if (!((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState)) {
|
|
2185
|
+
return platformAccountSummary;
|
|
2186
|
+
}
|
|
2187
|
+
const clearinghouseState = this.webData2.clearinghouseState;
|
|
2188
|
+
// Calculate total limit order value from platform orders
|
|
2189
|
+
const totalLimitOrderValue = this.calculateTotalLimitOrderValue(platformOpenOrders || []);
|
|
2190
|
+
// Use real-time data from webData2 clearinghouseState
|
|
2191
|
+
const withdrawableAmount = parseFloat(clearinghouseState.withdrawable || '0');
|
|
2192
|
+
const adjustedWithdrawable = Math.max(0, withdrawableAmount - totalLimitOrderValue);
|
|
2193
|
+
const accountSummary = {
|
|
2194
|
+
balanceSummary: {
|
|
2195
|
+
crossMaintenanceMarginUsed: clearinghouseState.crossMaintenanceMarginUsed || '0',
|
|
2196
|
+
crossMarginSummary: {
|
|
2197
|
+
accountValue: ((_b = clearinghouseState.crossMarginSummary) === null || _b === void 0 ? void 0 : _b.accountValue) || '0',
|
|
2198
|
+
totalMarginUsed: ((_c = clearinghouseState.crossMarginSummary) === null || _c === void 0 ? void 0 : _c.totalMarginUsed) || '0',
|
|
2199
|
+
totalNtlPos: ((_d = clearinghouseState.crossMarginSummary) === null || _d === void 0 ? void 0 : _d.totalNtlPos) || '0',
|
|
2200
|
+
totalRawUsd: ((_e = clearinghouseState.crossMarginSummary) === null || _e === void 0 ? void 0 : _e.totalRawUsd) || '0'
|
|
2201
|
+
},
|
|
2202
|
+
marginSummary: {
|
|
2203
|
+
accountValue: ((_f = clearinghouseState.marginSummary) === null || _f === void 0 ? void 0 : _f.accountValue) || '0',
|
|
2204
|
+
totalMarginUsed: ((_g = clearinghouseState.marginSummary) === null || _g === void 0 ? void 0 : _g.totalMarginUsed) || '0',
|
|
2205
|
+
totalNtlPos: ((_h = clearinghouseState.marginSummary) === null || _h === void 0 ? void 0 : _h.totalNtlPos) || '0',
|
|
2206
|
+
totalRawUsd: ((_j = clearinghouseState.marginSummary) === null || _j === void 0 ? void 0 : _j.totalRawUsd) || '0'
|
|
2207
|
+
},
|
|
2208
|
+
time: clearinghouseState.time || Date.now(),
|
|
2209
|
+
withdrawable: adjustedWithdrawable.toString()
|
|
2210
|
+
},
|
|
2211
|
+
agentWallet: {
|
|
2212
|
+
address: agentWalletAddress || ((_k = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWallet) === null || _k === void 0 ? void 0 : _k.address) || '',
|
|
2213
|
+
status: agentWalletStatus || ((_l = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWallet) === null || _l === void 0 ? void 0 : _l.status) || 'UNKNOWN'
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
return accountSummary;
|
|
2217
|
+
}
|
|
2218
|
+
/**
|
|
2219
|
+
* Calculate total USD value of open limit orders
|
|
2220
|
+
*/
|
|
2221
|
+
calculateTotalLimitOrderValue(openOrders) {
|
|
2222
|
+
if (!(openOrders === null || openOrders === void 0 ? void 0 : openOrders.length)) {
|
|
2223
|
+
return 0;
|
|
2224
|
+
}
|
|
2225
|
+
const totalValue = openOrders
|
|
2226
|
+
.filter(order => order.status === 'OPEN' || order.status === 'PROCESSING')
|
|
2227
|
+
.reduce((sum, order) => sum + order.usdValue / order.leverage, 0);
|
|
2228
|
+
return totalValue;
|
|
2229
|
+
}
|
|
2230
|
+
/**
|
|
2231
|
+
* Get real-time clearinghouse state from webData2
|
|
2232
|
+
*/
|
|
2233
|
+
getClearinghouseState() {
|
|
2234
|
+
var _a;
|
|
2235
|
+
return ((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState) || null;
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* Check if real-time data is available
|
|
2239
|
+
*/
|
|
2240
|
+
hasRealTimeData() {
|
|
2241
|
+
var _a;
|
|
2242
|
+
return !!((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
var PositionSide;
|
|
2247
|
+
(function (PositionSide) {
|
|
2248
|
+
PositionSide["LONG"] = "LONG";
|
|
2249
|
+
PositionSide["SHORT"] = "SHORT";
|
|
2250
|
+
})(PositionSide || (PositionSide = {}));
|
|
2251
|
+
class PositionProcessor {
|
|
2252
|
+
constructor(webData2, allMids) {
|
|
2253
|
+
this.webData2 = webData2;
|
|
2254
|
+
this.allMids = allMids;
|
|
2255
|
+
}
|
|
2256
|
+
execute(rawPositions) {
|
|
2257
|
+
if (!rawPositions || rawPositions.length === 0) {
|
|
2258
|
+
return [];
|
|
2259
|
+
}
|
|
2260
|
+
const userHyperliquidPositions = this.getUserPositions();
|
|
2261
|
+
const platformTotalsByAsset = this.calculatePlatformTotalsByAsset(rawPositions);
|
|
2262
|
+
const hlPositionsMap = new Map();
|
|
2263
|
+
(userHyperliquidPositions || []).forEach(assetPos => {
|
|
2264
|
+
var _a;
|
|
2265
|
+
if ((_a = assetPos.position) === null || _a === void 0 ? void 0 : _a.coin) {
|
|
2266
|
+
hlPositionsMap.set(assetPos.position.coin, assetPos);
|
|
2267
|
+
}
|
|
2268
|
+
});
|
|
2269
|
+
const openPositionDtos = [];
|
|
2270
|
+
for (const position of rawPositions) {
|
|
2271
|
+
const syncedPositionDto = this.syncPositionWithAggregateData(position, hlPositionsMap, platformTotalsByAsset);
|
|
2272
|
+
openPositionDtos.push(syncedPositionDto);
|
|
2273
|
+
}
|
|
2274
|
+
return openPositionDtos;
|
|
2275
|
+
}
|
|
2276
|
+
getUserPositions() {
|
|
2277
|
+
var _a, _b;
|
|
2278
|
+
return ((_b = (_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState) === null || _b === void 0 ? void 0 : _b.assetPositions) || [];
|
|
2279
|
+
}
|
|
2280
|
+
getMarketPrice(coin) {
|
|
2281
|
+
var _a;
|
|
2282
|
+
if (!((_a = this.allMids) === null || _a === void 0 ? void 0 : _a.mids))
|
|
2283
|
+
return 0;
|
|
2284
|
+
const exactPrice = this.allMids.mids[coin];
|
|
2285
|
+
if (exactPrice) {
|
|
2286
|
+
return Number(exactPrice);
|
|
2287
|
+
}
|
|
2288
|
+
const baseCurrency = this.extractBaseCurrency(coin);
|
|
2289
|
+
const basePrice = this.allMids.mids[baseCurrency];
|
|
2290
|
+
if (basePrice) {
|
|
2291
|
+
return Number(basePrice);
|
|
2292
|
+
}
|
|
2293
|
+
return 0;
|
|
2294
|
+
}
|
|
2295
|
+
calculatePlatformTotalsByAsset(positions) {
|
|
2296
|
+
const totalsMap = new Map();
|
|
2297
|
+
for (const position of positions) {
|
|
2298
|
+
for (const asset of position.longAssets || []) {
|
|
2299
|
+
const baseCurrency = this.extractBaseCurrency(asset.coin);
|
|
2300
|
+
if (!totalsMap.has(baseCurrency)) {
|
|
2301
|
+
totalsMap.set(baseCurrency, {
|
|
2302
|
+
totalSize: 0,
|
|
2303
|
+
positions: []
|
|
2304
|
+
});
|
|
2305
|
+
}
|
|
2306
|
+
const totals = totalsMap.get(baseCurrency);
|
|
2307
|
+
const assetSize = Number(asset.size || 0);
|
|
2308
|
+
totals.totalSize += assetSize;
|
|
2309
|
+
totals.positions.push({
|
|
2310
|
+
positionId: position.positionId,
|
|
2311
|
+
asset: asset,
|
|
2312
|
+
size: assetSize
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
for (const asset of position.shortAssets || []) {
|
|
2316
|
+
const baseCurrency = this.extractBaseCurrency(asset.coin);
|
|
2317
|
+
if (!totalsMap.has(baseCurrency)) {
|
|
2318
|
+
totalsMap.set(baseCurrency, {
|
|
2319
|
+
totalSize: 0,
|
|
2320
|
+
positions: []
|
|
2321
|
+
});
|
|
2322
|
+
}
|
|
2323
|
+
const totals = totalsMap.get(baseCurrency);
|
|
2324
|
+
const assetSize = Number(asset.size || 0);
|
|
2325
|
+
totals.totalSize += assetSize;
|
|
2326
|
+
totals.positions.push({
|
|
2327
|
+
positionId: position.positionId,
|
|
2328
|
+
asset: asset,
|
|
2329
|
+
size: assetSize
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
return totalsMap;
|
|
2334
|
+
}
|
|
2335
|
+
extractBaseCurrency(assetName) {
|
|
2336
|
+
return assetName.split('/')[0] || assetName;
|
|
2337
|
+
}
|
|
2338
|
+
syncPositionWithAggregateData(position, hlPositionsMap, platformTotalsByAsset) {
|
|
2339
|
+
const syncResults = [];
|
|
2340
|
+
let hasExternalModification = false;
|
|
2341
|
+
let allAssetsClosed = true;
|
|
2342
|
+
let longAssetStatuses = { total: 0, closed: 0 };
|
|
2343
|
+
let shortAssetStatuses = { total: 0, closed: 0 };
|
|
2344
|
+
// Process long assets
|
|
2345
|
+
for (const asset of position.longAssets || []) {
|
|
2346
|
+
const baseCurrency = this.extractBaseCurrency(asset.coin);
|
|
2347
|
+
const hlPosition = hlPositionsMap.get(baseCurrency);
|
|
2348
|
+
const platformTotals = platformTotalsByAsset.get(baseCurrency);
|
|
2349
|
+
const syncResult = this.syncAssetWithAggregateData({ ...asset, side: PositionSide.LONG }, hlPosition, (platformTotals === null || platformTotals === void 0 ? void 0 : platformTotals.totalSize) || 0);
|
|
2350
|
+
syncResults.push(syncResult);
|
|
2351
|
+
longAssetStatuses.total++;
|
|
2352
|
+
if (syncResult.actualSize === 0) {
|
|
2353
|
+
longAssetStatuses.closed++;
|
|
2354
|
+
}
|
|
2355
|
+
if (syncResult.isExternallyModified) {
|
|
2356
|
+
hasExternalModification = true;
|
|
2357
|
+
}
|
|
2358
|
+
if (syncResult.actualSize !== 0) {
|
|
2359
|
+
allAssetsClosed = false;
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
// Process short assets
|
|
2363
|
+
for (const asset of position.shortAssets || []) {
|
|
2364
|
+
const baseCurrency = this.extractBaseCurrency(asset.coin);
|
|
2365
|
+
const hlPosition = hlPositionsMap.get(baseCurrency);
|
|
2366
|
+
const platformTotals = platformTotalsByAsset.get(baseCurrency);
|
|
2367
|
+
const syncResult = this.syncAssetWithAggregateData({ ...asset, side: PositionSide.SHORT }, hlPosition, (platformTotals === null || platformTotals === void 0 ? void 0 : platformTotals.totalSize) || 0);
|
|
2368
|
+
syncResults.push(syncResult);
|
|
2369
|
+
shortAssetStatuses.total++;
|
|
2370
|
+
if (syncResult.actualSize === 0) {
|
|
2371
|
+
shortAssetStatuses.closed++;
|
|
2372
|
+
}
|
|
2373
|
+
if (syncResult.isExternallyModified) {
|
|
2374
|
+
hasExternalModification = true;
|
|
2375
|
+
}
|
|
2376
|
+
if (syncResult.actualSize !== 0) {
|
|
2377
|
+
allAssetsClosed = false;
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
const syncStatus = this.determineSyncStatus(hasExternalModification, allAssetsClosed, longAssetStatuses, shortAssetStatuses);
|
|
2381
|
+
return this.mapPositionToDtoWithSyncData(position, syncResults, syncStatus);
|
|
2382
|
+
}
|
|
2383
|
+
determineSyncStatus(hasExternalModification, allAssetsClosed, longAssetStatuses, shortAssetStatuses) {
|
|
2384
|
+
if (allAssetsClosed) {
|
|
2385
|
+
return 'EXTERNALLY_CLOSED';
|
|
2386
|
+
}
|
|
2387
|
+
const allLongsClosed = longAssetStatuses.total > 0 &&
|
|
2388
|
+
longAssetStatuses.closed === longAssetStatuses.total;
|
|
2389
|
+
const allShortsClosed = shortAssetStatuses.total > 0 &&
|
|
2390
|
+
shortAssetStatuses.closed === shortAssetStatuses.total;
|
|
2391
|
+
if ((allLongsClosed && !allShortsClosed) || (!allLongsClosed && allShortsClosed)) {
|
|
2392
|
+
return 'PAIR_BROKEN';
|
|
2393
|
+
}
|
|
2394
|
+
if (hasExternalModification) {
|
|
2395
|
+
return 'EXTERNALLY_MODIFIED';
|
|
2396
|
+
}
|
|
2397
|
+
return 'SYNCED';
|
|
2398
|
+
}
|
|
2399
|
+
syncAssetWithAggregateData(asset, hlPosition, platformTotal) {
|
|
2400
|
+
const platformSize = Number(asset.size || 0);
|
|
2401
|
+
if (!hlPosition || !hlPosition.position || !hlPosition.position.szi) {
|
|
2402
|
+
return {
|
|
2403
|
+
asset,
|
|
2404
|
+
actualSize: 0,
|
|
2405
|
+
isExternallyModified: true,
|
|
2406
|
+
cumFunding: { allTime: 0, sinceChange: 0, sinceOpen: 0 },
|
|
2407
|
+
unrealizedPnl: 0,
|
|
2408
|
+
liquidationPrice: 0
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
const hlTotalSize = Math.abs(Number(hlPosition.position.szi || 0));
|
|
2412
|
+
const totalDifference = Math.abs(hlTotalSize - platformTotal);
|
|
2413
|
+
const tolerance = platformTotal * 0.001;
|
|
2414
|
+
const isExternallyModified = totalDifference > tolerance;
|
|
2415
|
+
const proportion = platformTotal > 0 ? platformSize / platformTotal : 0;
|
|
2416
|
+
const actualSize = hlTotalSize * proportion;
|
|
2417
|
+
// Get cumFunding from hlPosition.position.cumFunding
|
|
2418
|
+
const rawCumFunding = hlPosition.position.cumFunding;
|
|
2419
|
+
const cumFunding = {
|
|
2420
|
+
allTime: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.allTime) || 0),
|
|
2421
|
+
sinceChange: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.sinceChange) || 0) * proportion,
|
|
2422
|
+
sinceOpen: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.sinceOpen) || 0) * proportion
|
|
2423
|
+
};
|
|
2424
|
+
const unrealizedPnl = Number(hlPosition.position.unrealizedPnl || 0) * proportion;
|
|
2425
|
+
const liquidationPrice = Number(hlPosition.position.liquidationPx || 0);
|
|
2426
|
+
return {
|
|
2427
|
+
asset,
|
|
2428
|
+
actualSize,
|
|
2429
|
+
isExternallyModified,
|
|
2430
|
+
cumFunding,
|
|
2431
|
+
unrealizedPnl,
|
|
2432
|
+
liquidationPrice
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
mapPositionToDtoWithSyncData(position, syncResults, syncStatus) {
|
|
2436
|
+
var _a, _b;
|
|
2437
|
+
const longAssets = ((_a = position.longAssets) === null || _a === void 0 ? void 0 : _a.filter(asset => asset)) || [];
|
|
2438
|
+
const shortAssets = ((_b = position.shortAssets) === null || _b === void 0 ? void 0 : _b.filter(asset => asset)) || [];
|
|
2439
|
+
const syncResultsMap = new Map();
|
|
2440
|
+
syncResults.forEach(result => {
|
|
2441
|
+
syncResultsMap.set(`${result.asset.coin}-${result.asset.side}`, result);
|
|
2442
|
+
});
|
|
2443
|
+
const currentTotalPositionValue = this.calculateCurrentTotalPositionValue(syncResults);
|
|
2444
|
+
const entryTotalPositionValue = this.calculateEntryTotalPositionValue(syncResults);
|
|
2445
|
+
const totalMarginUsed = entryTotalPositionValue / position.leverage;
|
|
2446
|
+
return {
|
|
2447
|
+
syncStatus: syncStatus,
|
|
2448
|
+
positionId: position.positionId,
|
|
2449
|
+
address: position.address,
|
|
2450
|
+
leverage: position.leverage,
|
|
2451
|
+
stopLoss: position.stopLoss,
|
|
2452
|
+
takeProfit: position.takeProfit,
|
|
2453
|
+
entryRatio: this.calculateEntryRatio(syncResults),
|
|
2454
|
+
markRatio: this.calculateMarkRatio(syncResults),
|
|
2455
|
+
netFunding: this.calculateNetFundingFromSyncResults(syncResults),
|
|
2456
|
+
positionValue: currentTotalPositionValue,
|
|
2457
|
+
marginUsed: totalMarginUsed,
|
|
2458
|
+
unrealizedPnl: this.calculateTotalUnrealizedPnlFromSyncResults(syncResults),
|
|
2459
|
+
lastSyncAt: new Date().toISOString(),
|
|
2460
|
+
longAssets: longAssets.map(asset => this.mapAssetToDetailDto(asset, syncResultsMap.get(`${asset.coin}-LONG`))),
|
|
2461
|
+
shortAssets: shortAssets.map(asset => this.mapAssetToDetailDto(asset, syncResultsMap.get(`${asset.coin}-SHORT`))),
|
|
2462
|
+
createdAt: position.createdAt,
|
|
2463
|
+
updatedAt: position.updatedAt
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
mapAssetToDetailDto(asset, syncData) {
|
|
2467
|
+
const currentPrice = this.getMarketPrice(asset.coin);
|
|
2468
|
+
const actualSize = (syncData === null || syncData === void 0 ? void 0 : syncData.actualSize) || Number(asset.size || 0);
|
|
2469
|
+
const positionValue = actualSize * currentPrice;
|
|
2470
|
+
const entryValue = Number(asset.size || 0) * Number(asset.entryPrice || 0);
|
|
2471
|
+
return {
|
|
2472
|
+
coin: asset.coin,
|
|
2473
|
+
entryPrice: Number(asset.entryPrice || 0),
|
|
2474
|
+
platformSize: Number(asset.size || 0),
|
|
2475
|
+
actualSize: actualSize,
|
|
2476
|
+
isExternallyModified: (syncData === null || syncData === void 0 ? void 0 : syncData.isExternallyModified) || false,
|
|
2477
|
+
cumFunding: (syncData === null || syncData === void 0 ? void 0 : syncData.cumFunding) || {
|
|
2478
|
+
allTime: 0,
|
|
2479
|
+
sinceChange: 0,
|
|
2480
|
+
sinceOpen: 0
|
|
2481
|
+
},
|
|
2482
|
+
marginUsed: entryValue,
|
|
2483
|
+
positionValue: positionValue,
|
|
2484
|
+
unrealizedPnl: (syncData === null || syncData === void 0 ? void 0 : syncData.unrealizedPnl) || 0,
|
|
2485
|
+
liquidationPrice: (syncData === null || syncData === void 0 ? void 0 : syncData.liquidationPrice) || 0
|
|
2486
|
+
};
|
|
2487
|
+
}
|
|
2488
|
+
calculateEntryRatio(syncResults) {
|
|
2489
|
+
var _a, _b;
|
|
2490
|
+
const longResults = syncResults.filter(result => result.asset.side === PositionSide.LONG);
|
|
2491
|
+
const shortResults = syncResults.filter(result => result.asset.side === PositionSide.SHORT);
|
|
2492
|
+
if (longResults.length === 0 || shortResults.length === 0)
|
|
2493
|
+
return 0;
|
|
2494
|
+
const longEntryPrice = ((_a = longResults[0]) === null || _a === void 0 ? void 0 : _a.asset.entryPrice) ? Number(longResults[0].asset.entryPrice) : 0;
|
|
2495
|
+
const shortEntryPrice = ((_b = shortResults[0]) === null || _b === void 0 ? void 0 : _b.asset.entryPrice) ? Number(shortResults[0].asset.entryPrice) : 0;
|
|
2496
|
+
return shortEntryPrice > 0 ? longEntryPrice / shortEntryPrice : 0;
|
|
2497
|
+
}
|
|
2498
|
+
calculateMarkRatio(syncResults) {
|
|
2499
|
+
var _a, _b;
|
|
2500
|
+
const longResults = syncResults.filter(result => result.asset.side === PositionSide.LONG);
|
|
2501
|
+
const shortResults = syncResults.filter(result => result.asset.side === PositionSide.SHORT);
|
|
2502
|
+
if (longResults.length === 0 || shortResults.length === 0)
|
|
2503
|
+
return 0;
|
|
2504
|
+
const longMarkPrice = ((_a = longResults[0]) === null || _a === void 0 ? void 0 : _a.asset.coin) ? this.getMarketPrice(longResults[0].asset.coin) : 0;
|
|
2505
|
+
const shortMarkPrice = ((_b = shortResults[0]) === null || _b === void 0 ? void 0 : _b.asset.coin) ? this.getMarketPrice(shortResults[0].asset.coin) : 0;
|
|
2506
|
+
return shortMarkPrice > 0 ? longMarkPrice / shortMarkPrice : 0;
|
|
2507
|
+
}
|
|
2508
|
+
calculateNetFundingFromSyncResults(syncResults) {
|
|
2509
|
+
const netFunding = syncResults.reduce((sum, result) => {
|
|
2510
|
+
const funding = result.cumFunding.sinceOpen;
|
|
2511
|
+
return sum + funding;
|
|
2512
|
+
}, 0);
|
|
2513
|
+
return netFunding;
|
|
2514
|
+
}
|
|
2515
|
+
calculateTotalUnrealizedPnlFromSyncResults(syncResults) {
|
|
2516
|
+
return syncResults.reduce((sum, result) => sum + result.unrealizedPnl, 0);
|
|
2517
|
+
}
|
|
2518
|
+
calculateCurrentTotalPositionValue(syncResults) {
|
|
2519
|
+
return syncResults.reduce((sum, result) => {
|
|
2520
|
+
const currentPrice = this.getMarketPrice(result.asset.coin);
|
|
2521
|
+
return sum + (result.actualSize * currentPrice);
|
|
2522
|
+
}, 0);
|
|
2523
|
+
}
|
|
2524
|
+
calculateEntryTotalPositionValue(syncResults) {
|
|
2525
|
+
return syncResults.reduce((sum, result) => {
|
|
2526
|
+
return sum + (Number(result.asset.size || 0) * Number(result.asset.entryPrice || 0));
|
|
2527
|
+
}, 0);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
const useTradeHistories = () => {
|
|
2532
|
+
const context = useContext(PearHyperliquidContext);
|
|
2533
|
+
if (!context) {
|
|
2534
|
+
throw new Error('useTradeHistories must be used within a PearHyperliquidProvider');
|
|
2535
|
+
}
|
|
2536
|
+
const tradeHistories = useUserData((state) => state.tradeHistories);
|
|
2537
|
+
const isLoading = useMemo(() => {
|
|
2538
|
+
return tradeHistories === null && context.isConnected;
|
|
2539
|
+
}, [tradeHistories, context.isConnected]);
|
|
2540
|
+
return {
|
|
2541
|
+
data: tradeHistories,
|
|
2542
|
+
isLoading
|
|
2543
|
+
};
|
|
2544
|
+
};
|
|
2545
|
+
/**
|
|
2546
|
+
* Hook to access open positions with real-time calculations and loading state
|
|
2547
|
+
*/
|
|
2548
|
+
const useOpenPositions = () => {
|
|
2549
|
+
const context = useContext(PearHyperliquidContext);
|
|
2550
|
+
if (!context) {
|
|
2551
|
+
throw new Error('useOpenPositions must be used within a PearHyperliquidProvider');
|
|
2552
|
+
}
|
|
2553
|
+
const userOpenPositions = useUserData((state) => state.rawOpenPositions);
|
|
2554
|
+
const webData2 = useHyperliquidData((state) => state.webData2);
|
|
2555
|
+
const allMids = useHyperliquidData((state) => state.allMids);
|
|
2556
|
+
const isLoading = useMemo(() => {
|
|
2557
|
+
return userOpenPositions === null && context.isConnected;
|
|
2558
|
+
}, [userOpenPositions, context.isConnected]);
|
|
2559
|
+
if (!userOpenPositions || !webData2 || !allMids) {
|
|
2560
|
+
return {
|
|
2561
|
+
data: null,
|
|
2562
|
+
isLoading
|
|
2563
|
+
};
|
|
2564
|
+
}
|
|
2565
|
+
const processor = new PositionProcessor(webData2, allMids);
|
|
2566
|
+
const processed = processor.execute(userOpenPositions);
|
|
2567
|
+
return {
|
|
2568
|
+
data: processed,
|
|
2569
|
+
isLoading
|
|
2570
|
+
};
|
|
2571
|
+
};
|
|
2572
|
+
/**
|
|
2573
|
+
* Hook to access open orders with loading state
|
|
2574
|
+
*/
|
|
2575
|
+
const useOpenOrders = () => {
|
|
2576
|
+
const context = useContext(PearHyperliquidContext);
|
|
2577
|
+
if (!context) {
|
|
2578
|
+
throw new Error('useOpenOrders must be used within a PearHyperliquidProvider');
|
|
2579
|
+
}
|
|
2580
|
+
const openOrders = useUserData((state) => state.openOrders);
|
|
2581
|
+
const isLoading = useMemo(() => {
|
|
2582
|
+
return openOrders === null && context.isConnected;
|
|
2583
|
+
}, [openOrders, context.isConnected]);
|
|
2584
|
+
return {
|
|
2585
|
+
data: openOrders,
|
|
2586
|
+
isLoading
|
|
2587
|
+
};
|
|
2588
|
+
};
|
|
2589
|
+
/**
|
|
2590
|
+
* Hook to access account summary with real-time calculations and loading state
|
|
2591
|
+
*/
|
|
2592
|
+
const useAccountSummary = () => {
|
|
2593
|
+
var _a, _b;
|
|
2594
|
+
const context = useContext(PearHyperliquidContext);
|
|
2595
|
+
if (!context) {
|
|
2596
|
+
throw new Error('useAccountSummary must be used within a PearHyperliquidProvider');
|
|
2597
|
+
}
|
|
2598
|
+
const openOrders = useUserData((state) => state.openOrders);
|
|
2599
|
+
const accountSummary = useUserData((state) => state.accountSummary);
|
|
2600
|
+
const webData2 = useHyperliquidData((state) => state.webData2);
|
|
2601
|
+
const isLoading = useMemo(() => {
|
|
2602
|
+
// Loading is true initially and becomes false once we get the first data
|
|
2603
|
+
return accountSummary === null && context.isConnected;
|
|
2604
|
+
}, [accountSummary, context.isConnected]);
|
|
2605
|
+
// Create calculator and compute account summary
|
|
2606
|
+
const calculator = new AccountSummaryCalculator(webData2);
|
|
2607
|
+
const calculated = calculator.calculateAccountSummary(accountSummary, openOrders, (_a = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _a === void 0 ? void 0 : _a.address, (_b = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _b === void 0 ? void 0 : _b.status);
|
|
2608
|
+
return {
|
|
2609
|
+
data: calculated,
|
|
2610
|
+
isLoading
|
|
2611
|
+
};
|
|
2612
|
+
};
|
|
2613
|
+
|
|
2614
|
+
const DEFAULT_STATE = {
|
|
2615
|
+
longTokens: [
|
|
2616
|
+
{ symbol: "HYPE", weight: 25 },
|
|
2617
|
+
{ symbol: "BTC", weight: 25 },
|
|
2618
|
+
],
|
|
2619
|
+
shortTokens: [
|
|
2620
|
+
{ symbol: "AVAX", weight: 10 },
|
|
2621
|
+
{ symbol: "SEI", weight: 10 },
|
|
2622
|
+
{ symbol: "ADA", weight: 10 },
|
|
2623
|
+
{ symbol: "TRUMP", weight: 10 },
|
|
2624
|
+
{ symbol: "SUI", weight: 10 },
|
|
2625
|
+
],
|
|
2626
|
+
openTokenSelector: false,
|
|
2627
|
+
selectorConfig: null,
|
|
2628
|
+
openConflictModal: false,
|
|
2629
|
+
conflicts: [],
|
|
2630
|
+
candleInterval: "1h",
|
|
2631
|
+
};
|
|
2632
|
+
const useUserSelection$1 = create((set, get) => ({
|
|
2633
|
+
...DEFAULT_STATE,
|
|
2634
|
+
setLongTokens: (tokens) => set((state) => ({ ...state, longTokens: tokens })),
|
|
2635
|
+
setShortTokens: (tokens) => set((state) => ({ ...state, shortTokens: tokens })),
|
|
2636
|
+
setOpenTokenSelector: (open) => set((state) => ({ ...state, openTokenSelector: open })),
|
|
2637
|
+
setSelectorConfig: (config) => set((state) => ({ ...state, selectorConfig: config })),
|
|
2638
|
+
setOpenConflictModal: (open) => set((state) => ({ ...state, openConflictModal: open })),
|
|
2639
|
+
setConflicts: (conflicts) => set((state) => ({ ...state, conflicts })),
|
|
2640
|
+
setCandleInterval: (interval) => set((state) => ({ ...state, candleInterval: interval })),
|
|
2641
|
+
updateTokenWeight: (isLong, index, newWeight) => {
|
|
2642
|
+
const clampedWeight = Math.max(1, Math.min(100, newWeight));
|
|
2643
|
+
set((prev) => {
|
|
2644
|
+
var _a, _b;
|
|
2645
|
+
const currentLongTotal = prev.longTokens.reduce((sum, t) => sum + t.weight, 0);
|
|
2646
|
+
const currentShortTotal = prev.shortTokens.reduce((sum, t) => sum + t.weight, 0);
|
|
2647
|
+
if (isLong) {
|
|
2648
|
+
const oldWeight = ((_a = prev.longTokens[index]) === null || _a === void 0 ? void 0 : _a.weight) || 0;
|
|
2649
|
+
const weightDiff = clampedWeight - oldWeight;
|
|
2650
|
+
const newLongTotal = currentLongTotal + weightDiff;
|
|
2651
|
+
if (newLongTotal + currentShortTotal > 100) {
|
|
2652
|
+
const maxAllowedWeight = Math.max(1, 100 - currentShortTotal - (currentLongTotal - oldWeight));
|
|
2653
|
+
const updated = [...prev.longTokens];
|
|
2654
|
+
updated[index] = { ...updated[index], weight: maxAllowedWeight };
|
|
2655
|
+
return { ...prev, longTokens: updated };
|
|
2656
|
+
}
|
|
2657
|
+
else {
|
|
2658
|
+
const updated = [...prev.longTokens];
|
|
2659
|
+
updated[index] = { ...updated[index], weight: clampedWeight };
|
|
2660
|
+
return { ...prev, longTokens: updated };
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
else {
|
|
2664
|
+
const oldWeight = ((_b = prev.shortTokens[index]) === null || _b === void 0 ? void 0 : _b.weight) || 0;
|
|
2665
|
+
const weightDiff = clampedWeight - oldWeight;
|
|
2666
|
+
const newShortTotal = currentShortTotal + weightDiff;
|
|
2667
|
+
if (currentLongTotal + newShortTotal > 100) {
|
|
2668
|
+
const maxAllowedWeight = Math.max(1, 100 - currentLongTotal - (currentShortTotal - oldWeight));
|
|
2669
|
+
const updated = [...prev.shortTokens];
|
|
2670
|
+
updated[index] = { ...updated[index], weight: maxAllowedWeight };
|
|
2671
|
+
return { ...prev, shortTokens: updated };
|
|
2672
|
+
}
|
|
2673
|
+
else {
|
|
2674
|
+
const updated = [...prev.shortTokens];
|
|
2675
|
+
updated[index] = { ...updated[index], weight: clampedWeight };
|
|
2676
|
+
return { ...prev, shortTokens: updated };
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
});
|
|
2680
|
+
},
|
|
2681
|
+
addToken: (isLong) => {
|
|
2682
|
+
const currentTokens = isLong ? get().longTokens : get().shortTokens;
|
|
2683
|
+
const newIndex = currentTokens.length;
|
|
2684
|
+
set((prev) => ({
|
|
2685
|
+
...prev,
|
|
2686
|
+
selectorConfig: { isLong, index: newIndex },
|
|
2687
|
+
openTokenSelector: true,
|
|
2688
|
+
}));
|
|
2689
|
+
},
|
|
2690
|
+
removeToken: (isLong, index) => {
|
|
2691
|
+
set((prev) => {
|
|
2692
|
+
if (isLong) {
|
|
2693
|
+
const updated = prev.longTokens.filter((_, i) => i !== index);
|
|
2694
|
+
return { ...prev, longTokens: updated };
|
|
2695
|
+
}
|
|
2696
|
+
else {
|
|
2697
|
+
const updated = prev.shortTokens.filter((_, i) => i !== index);
|
|
2698
|
+
return { ...prev, shortTokens: updated };
|
|
2699
|
+
}
|
|
2700
|
+
});
|
|
2701
|
+
},
|
|
2702
|
+
handleTokenSelect: (selectedToken) => {
|
|
2703
|
+
const { selectorConfig, longTokens, shortTokens } = get();
|
|
2704
|
+
if (!selectorConfig)
|
|
2705
|
+
return;
|
|
2706
|
+
const { isLong, index } = selectorConfig;
|
|
2707
|
+
const existingTokens = isLong ? longTokens : shortTokens;
|
|
2708
|
+
if (existingTokens.some((t) => t.symbol === selectedToken))
|
|
2709
|
+
return;
|
|
2710
|
+
set((prev) => {
|
|
2711
|
+
const longTotal = prev.longTokens.reduce((s, t) => s + t.weight, 0);
|
|
2712
|
+
const shortTotal = prev.shortTokens.reduce((s, t) => s + t.weight, 0);
|
|
2713
|
+
const currentTotal = longTotal + shortTotal;
|
|
2714
|
+
if (index >= existingTokens.length) {
|
|
2715
|
+
const maxAvailableWeight = Math.max(1, 100 - currentTotal);
|
|
2716
|
+
const safeWeight = Math.min(20, maxAvailableWeight);
|
|
2717
|
+
const newToken = { symbol: selectedToken, weight: safeWeight };
|
|
2718
|
+
if (isLong) {
|
|
2719
|
+
return {
|
|
2720
|
+
...prev,
|
|
2721
|
+
longTokens: [...prev.longTokens, newToken],
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
return {
|
|
2725
|
+
...prev,
|
|
2726
|
+
shortTokens: [...prev.shortTokens, newToken],
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2729
|
+
else {
|
|
2730
|
+
if (isLong) {
|
|
2731
|
+
const updated = [...prev.longTokens];
|
|
2732
|
+
updated[index] = { ...updated[index], symbol: selectedToken };
|
|
2733
|
+
return { ...prev, longTokens: updated };
|
|
2734
|
+
}
|
|
2735
|
+
else {
|
|
2736
|
+
const updated = [...prev.shortTokens];
|
|
2737
|
+
updated[index] = { ...updated[index], symbol: selectedToken };
|
|
2738
|
+
return { ...prev, shortTokens: updated };
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
});
|
|
2742
|
+
},
|
|
2743
|
+
resetToDefaults: () => set((prev) => ({ ...prev, ...DEFAULT_STATE })),
|
|
2744
|
+
}));
|
|
2745
|
+
|
|
2746
|
+
const useUserSelection = useUserSelection$1;
|
|
2747
|
+
|
|
2748
|
+
/**
|
|
2749
|
+
* Hook to access webData and native WebSocket state
|
|
2750
|
+
*/
|
|
2751
|
+
const useWebData = () => {
|
|
2752
|
+
var _a;
|
|
2753
|
+
const context = useContext(PearHyperliquidContext);
|
|
2754
|
+
if (!context) {
|
|
2755
|
+
throw new Error('useWebData must be used within a PearHyperliquidProvider');
|
|
2756
|
+
}
|
|
2757
|
+
const webData2 = useHyperliquidData((state) => state.webData2);
|
|
2758
|
+
let marketDataBySymbol = {};
|
|
2759
|
+
if ((webData2 === null || webData2 === void 0 ? void 0 : webData2.assetCtxs) && ((_a = webData2 === null || webData2 === void 0 ? void 0 : webData2.meta) === null || _a === void 0 ? void 0 : _a.universe)) {
|
|
2760
|
+
const { assetCtxs, meta: { universe } } = webData2;
|
|
2761
|
+
const result = {};
|
|
2762
|
+
for (let index = 0; index < universe.length; index++) {
|
|
2763
|
+
const name = universe[index].name;
|
|
2764
|
+
result[name] = {
|
|
2765
|
+
asset: assetCtxs[index],
|
|
2766
|
+
universe: universe[index],
|
|
2767
|
+
};
|
|
2768
|
+
}
|
|
2769
|
+
marketDataBySymbol = result;
|
|
2770
|
+
}
|
|
2771
|
+
return {
|
|
2772
|
+
clearinghouseState: webData2 === null || webData2 === void 0 ? void 0 : webData2.clearinghouseState,
|
|
2773
|
+
perpsAtOpenInterestCap: webData2 === null || webData2 === void 0 ? void 0 : webData2.perpsAtOpenInterestCap,
|
|
2774
|
+
marketDataBySymbol,
|
|
2775
|
+
isConnected: context.nativeIsConnected,
|
|
2776
|
+
connectionStatus: context.nativeConnectionStatus,
|
|
2777
|
+
error: context.nativeLastError
|
|
2778
|
+
};
|
|
2779
|
+
};
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* Extracts token metadata from WebData2 and AllMids data
|
|
2783
|
+
*/
|
|
2784
|
+
class TokenMetadataExtractor {
|
|
2785
|
+
/**
|
|
2786
|
+
* Extracts comprehensive token metadata
|
|
2787
|
+
* @param symbol - Token symbol
|
|
2788
|
+
* @param webData2 - WebData2 response containing asset context and universe data
|
|
2789
|
+
* @param allMids - AllMids data containing current prices
|
|
2790
|
+
* @param activeAssetData - Optional active asset data containing leverage information
|
|
2791
|
+
* @returns TokenMetadata or null if token not found
|
|
2792
|
+
*/
|
|
2793
|
+
static extractTokenMetadata(symbol, webData2, allMids, activeAssetData) {
|
|
2794
|
+
if (!webData2 || !allMids) {
|
|
2795
|
+
return null;
|
|
2796
|
+
}
|
|
2797
|
+
// Find token index in universe
|
|
2798
|
+
const universeIndex = webData2.meta.universe.findIndex(asset => asset.name === symbol);
|
|
2799
|
+
if (universeIndex === -1) {
|
|
2800
|
+
return null;
|
|
2801
|
+
}
|
|
2802
|
+
const universeAsset = webData2.meta.universe[universeIndex];
|
|
2803
|
+
const assetCtx = webData2.assetCtxs[universeIndex];
|
|
2804
|
+
if (!assetCtx) {
|
|
2805
|
+
return null;
|
|
2806
|
+
}
|
|
2807
|
+
// Get current price from allMids
|
|
2808
|
+
const currentPriceStr = allMids.mids[symbol];
|
|
2809
|
+
const currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
|
|
2810
|
+
// Get previous day price
|
|
2811
|
+
const prevDayPrice = parseFloat(assetCtx.prevDayPx);
|
|
2812
|
+
// Calculate 24h price change
|
|
2813
|
+
const priceChange24h = currentPrice - prevDayPrice;
|
|
2814
|
+
const priceChange24hPercent = prevDayPrice !== 0 ? (priceChange24h / prevDayPrice) * 100 : 0;
|
|
2815
|
+
// Parse other metadata
|
|
2816
|
+
const netFunding = parseFloat(assetCtx.funding) * 100;
|
|
2817
|
+
const markPrice = parseFloat(assetCtx.markPx);
|
|
2818
|
+
const oraclePrice = parseFloat(assetCtx.oraclePx);
|
|
2819
|
+
// Extract leverage info from activeAssetData if available
|
|
2820
|
+
const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[symbol];
|
|
2821
|
+
const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
|
|
2822
|
+
const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
|
|
2823
|
+
const availableToTrade = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.availableToTrade;
|
|
2824
|
+
return {
|
|
2825
|
+
currentPrice,
|
|
2826
|
+
prevDayPrice,
|
|
2827
|
+
priceChange24h,
|
|
2828
|
+
priceChange24hPercent,
|
|
2829
|
+
netFunding,
|
|
2830
|
+
maxLeverage: universeAsset.maxLeverage,
|
|
2831
|
+
markPrice,
|
|
2832
|
+
oraclePrice,
|
|
2833
|
+
openInterest: assetCtx.openInterest,
|
|
2834
|
+
dayVolume: assetCtx.dayNtlVlm,
|
|
2835
|
+
leverage,
|
|
2836
|
+
maxTradeSzs,
|
|
2837
|
+
availableToTrade,
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Extracts metadata for multiple tokens
|
|
2842
|
+
* @param symbols - Array of token symbols
|
|
2843
|
+
* @param webData2 - WebData2 response
|
|
2844
|
+
* @param allMids - AllMids data
|
|
2845
|
+
* @param activeAssetData - Optional active asset data containing leverage information
|
|
2846
|
+
* @returns Record of symbol to TokenMetadata
|
|
2847
|
+
*/
|
|
2848
|
+
static extractMultipleTokensMetadata(symbols, webData2, allMids, activeAssetData) {
|
|
2849
|
+
const result = {};
|
|
2850
|
+
for (const symbol of symbols) {
|
|
2851
|
+
result[symbol] = this.extractTokenMetadata(symbol, webData2, allMids, activeAssetData);
|
|
2852
|
+
}
|
|
2853
|
+
return result;
|
|
2854
|
+
}
|
|
2855
|
+
/**
|
|
2856
|
+
* Checks if token data is available in WebData2
|
|
2857
|
+
* @param symbol - Token symbol
|
|
2858
|
+
* @param webData2 - WebData2 response
|
|
2859
|
+
* @returns boolean indicating if token exists in universe
|
|
2860
|
+
*/
|
|
2861
|
+
static isTokenAvailable(symbol, webData2) {
|
|
2862
|
+
if (!webData2)
|
|
2863
|
+
return false;
|
|
2864
|
+
return webData2.meta.universe.some(asset => asset.name === symbol);
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
const useTokenSelectionMetadataStore = create((set) => ({
|
|
2869
|
+
isPriceDataReady: false,
|
|
2870
|
+
isLoading: true,
|
|
2871
|
+
longTokensMetadata: {},
|
|
2872
|
+
shortTokensMetadata: {},
|
|
2873
|
+
weightedRatio: 1,
|
|
2874
|
+
weightedRatio24h: 1,
|
|
2875
|
+
sumNetFunding: 0,
|
|
2876
|
+
maxLeverage: 0,
|
|
2877
|
+
minMargin: 0,
|
|
2878
|
+
leverageMatched: true,
|
|
2879
|
+
recompute: ({ webData2, allMids, activeAssetData, longTokens, shortTokens }) => {
|
|
2880
|
+
const isPriceDataReady = !!(webData2 && allMids);
|
|
2881
|
+
// Compute metadata when ready
|
|
2882
|
+
const longSymbols = longTokens.map((t) => t.symbol);
|
|
2883
|
+
const shortSymbols = shortTokens.map((t) => t.symbol);
|
|
2884
|
+
const longTokensMetadata = isPriceDataReady
|
|
2885
|
+
? TokenMetadataExtractor.extractMultipleTokensMetadata(longSymbols, webData2, allMids, activeAssetData)
|
|
2886
|
+
: {};
|
|
2887
|
+
const shortTokensMetadata = isPriceDataReady
|
|
2888
|
+
? TokenMetadataExtractor.extractMultipleTokensMetadata(shortSymbols, webData2, allMids, activeAssetData)
|
|
2889
|
+
: {};
|
|
2890
|
+
// Determine loading state
|
|
2891
|
+
const allTokens = [...longTokens, ...shortTokens];
|
|
2892
|
+
const isLoading = (() => {
|
|
2893
|
+
if (!isPriceDataReady)
|
|
2894
|
+
return true;
|
|
2895
|
+
if (allTokens.length === 0)
|
|
2896
|
+
return false;
|
|
2897
|
+
const allMetadata = { ...longTokensMetadata, ...shortTokensMetadata };
|
|
2898
|
+
return allTokens.some((token) => !allMetadata[token.symbol]);
|
|
2899
|
+
})();
|
|
2900
|
+
// Weighted ratio (current)
|
|
2901
|
+
const weightedRatio = (() => {
|
|
2902
|
+
let longProduct = 1;
|
|
2903
|
+
let shortProduct = 1;
|
|
2904
|
+
longTokens.forEach((token) => {
|
|
2905
|
+
const metadata = longTokensMetadata[token.symbol];
|
|
2906
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.currentPrice) && token.weight > 0) {
|
|
2907
|
+
const weightFactor = token.weight / 100;
|
|
2908
|
+
longProduct *= Math.pow(metadata.currentPrice, weightFactor);
|
|
2909
|
+
}
|
|
2910
|
+
});
|
|
2911
|
+
shortTokens.forEach((token) => {
|
|
2912
|
+
const metadata = shortTokensMetadata[token.symbol];
|
|
2913
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.currentPrice) && token.weight > 0) {
|
|
2914
|
+
const weightFactor = token.weight / 100;
|
|
2915
|
+
shortProduct *= Math.pow(metadata.currentPrice, -weightFactor);
|
|
2916
|
+
}
|
|
2917
|
+
});
|
|
2918
|
+
return longProduct * shortProduct;
|
|
2919
|
+
})();
|
|
2920
|
+
// Weighted ratio (24h, using previous day prices)
|
|
2921
|
+
const weightedRatio24h = (() => {
|
|
2922
|
+
let longProduct = 1;
|
|
2923
|
+
let shortProduct = 1;
|
|
2924
|
+
longTokens.forEach((token) => {
|
|
2925
|
+
const metadata = longTokensMetadata[token.symbol];
|
|
2926
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.prevDayPrice) && token.weight > 0) {
|
|
2927
|
+
const weightFactor = token.weight / 100;
|
|
2928
|
+
longProduct *= Math.pow(metadata.prevDayPrice, weightFactor);
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
shortTokens.forEach((token) => {
|
|
2932
|
+
const metadata = shortTokensMetadata[token.symbol];
|
|
2933
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.prevDayPrice) && token.weight > 0) {
|
|
2934
|
+
const weightFactor = token.weight / 100;
|
|
2935
|
+
shortProduct *= Math.pow(metadata.prevDayPrice, -weightFactor);
|
|
2936
|
+
}
|
|
2937
|
+
});
|
|
2938
|
+
return longProduct * shortProduct;
|
|
2939
|
+
})();
|
|
2940
|
+
// Sum of weighted net funding
|
|
2941
|
+
const sumNetFunding = (() => {
|
|
2942
|
+
let totalFunding = 0;
|
|
2943
|
+
longTokens.forEach((token) => {
|
|
2944
|
+
const metadata = longTokensMetadata[token.symbol];
|
|
2945
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.netFunding) && token.weight > 0) {
|
|
2946
|
+
const weightFactor = token.weight / 100;
|
|
2947
|
+
totalFunding += metadata.netFunding * weightFactor;
|
|
2948
|
+
}
|
|
2949
|
+
});
|
|
2950
|
+
shortTokens.forEach((token) => {
|
|
2951
|
+
const metadata = shortTokensMetadata[token.symbol];
|
|
2952
|
+
if ((metadata === null || metadata === void 0 ? void 0 : metadata.netFunding) && token.weight > 0) {
|
|
2953
|
+
const weightFactor = token.weight / 100;
|
|
2954
|
+
totalFunding -= metadata.netFunding * weightFactor;
|
|
2955
|
+
}
|
|
2956
|
+
});
|
|
2957
|
+
return totalFunding * 100;
|
|
2958
|
+
})();
|
|
2959
|
+
// Max leverage (minimum across all tokens)
|
|
2960
|
+
const maxLeverage = (() => {
|
|
2961
|
+
var _a;
|
|
2962
|
+
if (!((_a = webData2 === null || webData2 === void 0 ? void 0 : webData2.meta) === null || _a === void 0 ? void 0 : _a.universe))
|
|
2963
|
+
return 0;
|
|
2964
|
+
const allTokenSymbols = [...longTokens, ...shortTokens].map((t) => t.symbol);
|
|
2965
|
+
if (allTokenSymbols.length === 0)
|
|
2966
|
+
return 0;
|
|
2967
|
+
let minLev = Infinity;
|
|
2968
|
+
allTokenSymbols.forEach((symbol) => {
|
|
2969
|
+
const tokenUniverse = webData2.meta.universe.find((u) => u.name === symbol);
|
|
2970
|
+
if (tokenUniverse === null || tokenUniverse === void 0 ? void 0 : tokenUniverse.maxLeverage)
|
|
2971
|
+
minLev = Math.min(minLev, tokenUniverse.maxLeverage);
|
|
2972
|
+
});
|
|
2973
|
+
return minLev === Infinity ? 0 : minLev;
|
|
2974
|
+
})();
|
|
2975
|
+
// Min margin (10 * total number of tokens)
|
|
2976
|
+
const minMargin = (() => {
|
|
2977
|
+
const totalTokenCount = longTokens.length + shortTokens.length;
|
|
2978
|
+
return 10 * totalTokenCount;
|
|
2979
|
+
})();
|
|
2980
|
+
// Whether all tokens have matching leverage
|
|
2981
|
+
const leverageMatched = (() => {
|
|
2982
|
+
const allTokensArr = [...longTokens, ...shortTokens];
|
|
2983
|
+
const allMetadata = { ...longTokensMetadata, ...shortTokensMetadata };
|
|
2984
|
+
if (allTokensArr.length === 0)
|
|
2985
|
+
return true;
|
|
2986
|
+
const tokensWithLev = allTokensArr.filter((token) => { var _a; return (_a = allMetadata[token.symbol]) === null || _a === void 0 ? void 0 : _a.leverage; });
|
|
2987
|
+
if (tokensWithLev.length === 0)
|
|
2988
|
+
return false;
|
|
2989
|
+
if (tokensWithLev.length < allTokensArr.length)
|
|
2990
|
+
return false;
|
|
2991
|
+
const firstLev = allMetadata[tokensWithLev[0].symbol].leverage;
|
|
2992
|
+
return tokensWithLev.every((token) => {
|
|
2993
|
+
const lev = allMetadata[token.symbol].leverage;
|
|
2994
|
+
return lev.type === firstLev.type && lev.value === firstLev.value;
|
|
2995
|
+
});
|
|
2996
|
+
})();
|
|
2997
|
+
set({
|
|
2998
|
+
isPriceDataReady,
|
|
2999
|
+
isLoading,
|
|
3000
|
+
longTokensMetadata,
|
|
3001
|
+
shortTokensMetadata,
|
|
3002
|
+
weightedRatio,
|
|
3003
|
+
weightedRatio24h,
|
|
3004
|
+
sumNetFunding,
|
|
3005
|
+
maxLeverage,
|
|
3006
|
+
minMargin,
|
|
3007
|
+
leverageMatched,
|
|
3008
|
+
});
|
|
3009
|
+
},
|
|
3010
|
+
}));
|
|
3011
|
+
|
|
3012
|
+
const useTokenSelectionMetadata = () => {
|
|
3013
|
+
const context = useContext(PearHyperliquidContext);
|
|
3014
|
+
if (!context) {
|
|
3015
|
+
throw new Error('useTokenSelection must be used within PearHyperliquidProvider');
|
|
3016
|
+
}
|
|
3017
|
+
const webData2 = useHyperliquidData((state) => state.webData2);
|
|
3018
|
+
const allMids = useHyperliquidData((state) => state.allMids);
|
|
3019
|
+
const activeAssetData = useHyperliquidData((state) => state.activeAssetData);
|
|
3020
|
+
const { longTokens, shortTokens } = useUserSelection$1();
|
|
3021
|
+
const { isLoading, isPriceDataReady, longTokensMetadata, shortTokensMetadata, weightedRatio, weightedRatio24h, sumNetFunding, maxLeverage, minMargin, leverageMatched, recompute, } = useTokenSelectionMetadataStore();
|
|
3022
|
+
// Recompute derived metadata when inputs change
|
|
3023
|
+
useEffect(() => {
|
|
3024
|
+
recompute({
|
|
3025
|
+
webData2,
|
|
3026
|
+
allMids,
|
|
3027
|
+
activeAssetData: activeAssetData || null,
|
|
3028
|
+
longTokens,
|
|
3029
|
+
shortTokens,
|
|
3030
|
+
});
|
|
3031
|
+
// We want to recompute when token lists or upstream data change
|
|
3032
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3033
|
+
}, [webData2, allMids, activeAssetData, JSON.stringify(longTokens), JSON.stringify(shortTokens)]);
|
|
3034
|
+
return {
|
|
3035
|
+
// Loading states
|
|
3036
|
+
isLoading,
|
|
3037
|
+
isPriceDataReady,
|
|
3038
|
+
longTokensMetadata,
|
|
3039
|
+
shortTokensMetadata,
|
|
3040
|
+
// Calculated values
|
|
3041
|
+
weightedRatio,
|
|
3042
|
+
weightedRatio24h,
|
|
3043
|
+
sumNetFunding,
|
|
3044
|
+
maxLeverage,
|
|
3045
|
+
minMargin,
|
|
3046
|
+
leverageMatched,
|
|
3047
|
+
};
|
|
3048
|
+
};
|
|
3049
|
+
|
|
3050
|
+
const createKey = (symbol, interval) => {
|
|
3051
|
+
return `${symbol}-${interval}`;
|
|
3052
|
+
};
|
|
3053
|
+
const useHistoricalPriceDataStore = create((set, get) => ({
|
|
3054
|
+
historicalPriceData: {},
|
|
3055
|
+
loadingTokens: new Set(),
|
|
3056
|
+
addHistoricalPriceData: (symbol, interval, candles, range) => {
|
|
3057
|
+
set(state => {
|
|
3058
|
+
const key = createKey(symbol, interval);
|
|
3059
|
+
const existing = state.historicalPriceData[key];
|
|
3060
|
+
if (!existing) {
|
|
3061
|
+
// Create new entry
|
|
3062
|
+
const sortedCandles = [...candles].sort((a, b) => a.t - b.t);
|
|
3063
|
+
return {
|
|
3064
|
+
historicalPriceData: {
|
|
3065
|
+
...state.historicalPriceData,
|
|
3066
|
+
[key]: {
|
|
3067
|
+
symbol,
|
|
3068
|
+
interval,
|
|
3069
|
+
candles: sortedCandles,
|
|
3070
|
+
oldestTime: sortedCandles.length > 0 ? sortedCandles[0].t : null,
|
|
3071
|
+
latestTime: sortedCandles.length > 0 ? sortedCandles[sortedCandles.length - 1].t : null
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
};
|
|
3075
|
+
}
|
|
3076
|
+
// Merge with existing data
|
|
3077
|
+
const existingTimes = new Set(existing.candles.map(c => c.t));
|
|
3078
|
+
const newCandles = candles.filter(c => !existingTimes.has(c.t));
|
|
3079
|
+
const mergedCandles = [...existing.candles, ...newCandles].sort((a, b) => a.t - b.t);
|
|
3080
|
+
// Update time pointers
|
|
3081
|
+
const oldestTime = mergedCandles.length > 0 ? mergedCandles[0].t : null;
|
|
3082
|
+
const latestTime = mergedCandles.length > 0 ? mergedCandles[mergedCandles.length - 1].t : null;
|
|
3083
|
+
return {
|
|
3084
|
+
historicalPriceData: {
|
|
3085
|
+
...state.historicalPriceData,
|
|
3086
|
+
[key]: {
|
|
3087
|
+
...existing,
|
|
3088
|
+
candles: mergedCandles,
|
|
3089
|
+
oldestTime,
|
|
3090
|
+
latestTime
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
};
|
|
3094
|
+
});
|
|
3095
|
+
},
|
|
3096
|
+
hasHistoricalPriceData: (symbol, interval, startTime, endTime) => {
|
|
3097
|
+
const { historicalPriceData } = get();
|
|
3098
|
+
const key = createKey(symbol, interval);
|
|
3099
|
+
const tokenData = historicalPriceData[key];
|
|
3100
|
+
if (!tokenData || tokenData.oldestTime === null || tokenData.latestTime === null)
|
|
3101
|
+
return false;
|
|
3102
|
+
// Check if our cached data covers the requested time range
|
|
3103
|
+
return tokenData.oldestTime <= startTime && tokenData.latestTime >= endTime;
|
|
3104
|
+
},
|
|
3105
|
+
getHistoricalPriceData: (symbol, interval, startTime, endTime) => {
|
|
3106
|
+
const { historicalPriceData } = get();
|
|
3107
|
+
const key = createKey(symbol, interval);
|
|
3108
|
+
const tokenData = historicalPriceData[key];
|
|
3109
|
+
if (!tokenData)
|
|
3110
|
+
return [];
|
|
3111
|
+
// Filter candles within the requested time range
|
|
3112
|
+
return tokenData.candles.filter(candle => candle.t >= startTime && candle.T <= endTime);
|
|
3113
|
+
},
|
|
3114
|
+
setTokenLoading: (symbol, loading) => {
|
|
3115
|
+
set(state => {
|
|
3116
|
+
const newLoadingTokens = new Set(state.loadingTokens);
|
|
3117
|
+
if (loading) {
|
|
3118
|
+
newLoadingTokens.add(symbol);
|
|
3119
|
+
}
|
|
3120
|
+
else {
|
|
3121
|
+
newLoadingTokens.delete(symbol);
|
|
3122
|
+
}
|
|
3123
|
+
return { loadingTokens: newLoadingTokens };
|
|
3124
|
+
});
|
|
3125
|
+
},
|
|
3126
|
+
isTokenLoading: (symbol) => {
|
|
3127
|
+
const { loadingTokens } = get();
|
|
3128
|
+
return loadingTokens.has(symbol);
|
|
3129
|
+
},
|
|
3130
|
+
removeTokenPriceData: (symbol, interval) => {
|
|
3131
|
+
set(state => {
|
|
3132
|
+
const key = createKey(symbol, interval);
|
|
3133
|
+
const newHistoricalPriceData = { ...state.historicalPriceData };
|
|
3134
|
+
delete newHistoricalPriceData[key];
|
|
3135
|
+
// Also clear loading state for this token
|
|
3136
|
+
const newLoadingTokens = new Set(state.loadingTokens);
|
|
3137
|
+
newLoadingTokens.delete(symbol);
|
|
3138
|
+
return {
|
|
3139
|
+
historicalPriceData: newHistoricalPriceData,
|
|
3140
|
+
loadingTokens: newLoadingTokens
|
|
3141
|
+
};
|
|
3142
|
+
});
|
|
3143
|
+
},
|
|
3144
|
+
clearData: () => set({
|
|
3145
|
+
historicalPriceData: {},
|
|
3146
|
+
loadingTokens: new Set()
|
|
3147
|
+
}),
|
|
3148
|
+
}));
|
|
3149
|
+
|
|
3150
|
+
const useHistoricalPriceData = () => {
|
|
3151
|
+
const context = useContext(PearHyperliquidContext);
|
|
3152
|
+
if (!context) {
|
|
3153
|
+
throw new Error('useHistoricalPriceData must be used within a PearHyperliquidProvider');
|
|
3154
|
+
}
|
|
3155
|
+
const { client } = context;
|
|
3156
|
+
const longTokens = useUserSelection$1((state) => state.longTokens);
|
|
3157
|
+
const shortTokens = useUserSelection$1((state) => state.shortTokens);
|
|
3158
|
+
const candleInterval = useUserSelection$1((state) => state.candleInterval);
|
|
3159
|
+
// Get real-time candle data from WebSocket
|
|
3160
|
+
const candleData = useHyperliquidData((state) => state.candleData);
|
|
3161
|
+
// Historical price data store
|
|
3162
|
+
const { addHistoricalPriceData, hasHistoricalPriceData: storeHasData, getHistoricalPriceData: storeGetData, setTokenLoading, isTokenLoading, removeTokenPriceData, clearData, } = useHistoricalPriceDataStore();
|
|
3163
|
+
// Track previous tokens and interval to detect changes
|
|
3164
|
+
const prevTokensRef = useRef(new Set());
|
|
3165
|
+
const prevIntervalRef = useRef(null);
|
|
3166
|
+
// Get all tokens from long and short selections
|
|
3167
|
+
const getAllTokens = useCallback(() => {
|
|
3168
|
+
return [...longTokens, ...shortTokens];
|
|
3169
|
+
}, [longTokens, shortTokens]);
|
|
3170
|
+
// Track token and interval changes and manage cache accordingly
|
|
3171
|
+
useEffect(() => {
|
|
3172
|
+
const currentTokens = new Set(getAllTokens().map(token => token.symbol));
|
|
3173
|
+
const prevTokens = prevTokensRef.current;
|
|
3174
|
+
const prevInterval = prevIntervalRef.current;
|
|
3175
|
+
if (prevInterval !== null && prevInterval !== candleInterval) {
|
|
3176
|
+
// Clear entire cache when interval changes
|
|
3177
|
+
clearData();
|
|
3178
|
+
prevTokensRef.current = currentTokens;
|
|
3179
|
+
prevIntervalRef.current = candleInterval;
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
const removedTokens = Array.from(prevTokens).filter(symbol => !currentTokens.has(symbol));
|
|
3183
|
+
// Clean up cache for removed tokens
|
|
3184
|
+
removedTokens.forEach(symbol => {
|
|
3185
|
+
removeTokenPriceData(symbol, candleInterval);
|
|
3186
|
+
});
|
|
3187
|
+
// Update the refs with current values
|
|
3188
|
+
prevTokensRef.current = currentTokens;
|
|
3189
|
+
prevIntervalRef.current = candleInterval;
|
|
3190
|
+
}, [longTokens, shortTokens, candleInterval, removeTokenPriceData, clearData, getAllTokens]);
|
|
3191
|
+
useEffect(() => {
|
|
3192
|
+
if (!candleData)
|
|
3193
|
+
return;
|
|
3194
|
+
const allTokenSymbols = new Set(getAllTokens().map(token => token.symbol));
|
|
3195
|
+
Object.entries(candleData).forEach(([symbol, candle]) => {
|
|
3196
|
+
if (allTokenSymbols.has(symbol)) {
|
|
3197
|
+
if (candle.i === candleInterval) {
|
|
3198
|
+
addHistoricalPriceData(symbol, candleInterval, [candle], { start: candle.t, end: candle.T });
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
});
|
|
3202
|
+
}, [candleData, getAllTokens, candleInterval, addHistoricalPriceData]);
|
|
3203
|
+
const hasHistoricalPriceData = useCallback((startTime, endTime) => {
|
|
3204
|
+
const allTokens = getAllTokens();
|
|
3205
|
+
if (allTokens.length === 0)
|
|
3206
|
+
return false;
|
|
3207
|
+
return allTokens.every(token => storeHasData(token.symbol, candleInterval, startTime, endTime));
|
|
3208
|
+
}, [getAllTokens, candleInterval, storeHasData]);
|
|
3209
|
+
const getHistoricalPriceData = useCallback((startTime, endTime) => {
|
|
3210
|
+
const allTokens = getAllTokens();
|
|
3211
|
+
const result = {};
|
|
3212
|
+
allTokens.forEach(token => {
|
|
3213
|
+
result[token.symbol] = storeGetData(token.symbol, candleInterval, startTime, endTime);
|
|
3214
|
+
});
|
|
3215
|
+
return result;
|
|
3216
|
+
}, [getAllTokens, candleInterval, storeGetData]);
|
|
3217
|
+
const isLoading = useCallback((symbol) => {
|
|
3218
|
+
if (symbol) {
|
|
3219
|
+
return isTokenLoading(symbol);
|
|
3220
|
+
}
|
|
3221
|
+
const allTokens = getAllTokens();
|
|
3222
|
+
return allTokens.some(token => isTokenLoading(token.symbol));
|
|
3223
|
+
}, [getAllTokens, isTokenLoading]);
|
|
3224
|
+
const fetchHistoricalPriceData = useCallback(async (startTime, endTime, callback) => {
|
|
3225
|
+
const allTokens = getAllTokens();
|
|
3226
|
+
if (allTokens.length === 0) {
|
|
3227
|
+
const emptyResult = {};
|
|
3228
|
+
callback === null || callback === void 0 ? void 0 : callback(emptyResult);
|
|
3229
|
+
return emptyResult;
|
|
3230
|
+
}
|
|
3231
|
+
const tokensToFetch = allTokens.filter(token => !storeHasData(token.symbol, candleInterval, startTime, endTime));
|
|
3232
|
+
if (tokensToFetch.length === 0) {
|
|
3233
|
+
const cachedData = getHistoricalPriceData(startTime, endTime);
|
|
3234
|
+
callback === null || callback === void 0 ? void 0 : callback(cachedData);
|
|
3235
|
+
return cachedData;
|
|
3236
|
+
}
|
|
3237
|
+
tokensToFetch.forEach(token => {
|
|
3238
|
+
setTokenLoading(token.symbol, true);
|
|
3239
|
+
});
|
|
3240
|
+
try {
|
|
3241
|
+
const fetchPromises = tokensToFetch.map(async (token) => {
|
|
3242
|
+
try {
|
|
3243
|
+
const response = await client.fetchHistoricalCandles(token.symbol, startTime, endTime, candleInterval);
|
|
3244
|
+
addHistoricalPriceData(token.symbol, candleInterval, response.data, { start: startTime, end: endTime });
|
|
3245
|
+
return { symbol: token.symbol, candles: response.data, success: true };
|
|
3246
|
+
}
|
|
3247
|
+
catch (error) {
|
|
3248
|
+
console.warn(`Failed to fetch historical data for ${token.symbol}:`, error);
|
|
3249
|
+
return { symbol: token.symbol, candles: [], success: false };
|
|
3250
|
+
}
|
|
3251
|
+
});
|
|
3252
|
+
await Promise.all(fetchPromises);
|
|
3253
|
+
const allData = getHistoricalPriceData(startTime, endTime);
|
|
3254
|
+
callback === null || callback === void 0 ? void 0 : callback(allData);
|
|
3255
|
+
return allData;
|
|
3256
|
+
}
|
|
3257
|
+
catch (error) {
|
|
3258
|
+
console.error('Failed to fetch historical data:', error);
|
|
3259
|
+
throw error;
|
|
3260
|
+
}
|
|
3261
|
+
finally {
|
|
3262
|
+
tokensToFetch.forEach(token => {
|
|
3263
|
+
setTokenLoading(token.symbol, false);
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
}, [
|
|
3267
|
+
getAllTokens,
|
|
3268
|
+
candleInterval,
|
|
3269
|
+
storeHasData,
|
|
3270
|
+
getHistoricalPriceData,
|
|
3271
|
+
setTokenLoading,
|
|
3272
|
+
client,
|
|
3273
|
+
addHistoricalPriceData,
|
|
3274
|
+
]);
|
|
3275
|
+
const clearCache = useCallback(() => {
|
|
3276
|
+
clearData();
|
|
3277
|
+
}, [clearData]);
|
|
3278
|
+
return {
|
|
3279
|
+
fetchHistoricalPriceData,
|
|
3280
|
+
hasHistoricalPriceData,
|
|
3281
|
+
getHistoricalPriceData,
|
|
3282
|
+
isLoading,
|
|
3283
|
+
clearCache,
|
|
3284
|
+
};
|
|
3285
|
+
};
|
|
3286
|
+
|
|
3287
|
+
/**
|
|
3288
|
+
* Create efficient timestamp-based lookup maps for candle data
|
|
3289
|
+
*/
|
|
3290
|
+
const createCandleLookups = (tokenCandles) => {
|
|
3291
|
+
const lookups = {};
|
|
3292
|
+
Object.entries(tokenCandles).forEach(([symbol, candles]) => {
|
|
3293
|
+
const lookup = new Map();
|
|
3294
|
+
candles.forEach(candle => lookup.set(candle.t, candle));
|
|
3295
|
+
lookups[symbol] = lookup;
|
|
3296
|
+
});
|
|
3297
|
+
return lookups;
|
|
3298
|
+
};
|
|
3299
|
+
/**
|
|
3300
|
+
* Calculate weighted ratio for a specific price type (open, high, low, close)
|
|
3301
|
+
* Uses the formula: LONG_PRODUCT * SHORT_PRODUCT
|
|
3302
|
+
* Where LONG_PRODUCT = ∏(PRICE^(WEIGHT/100)) for long tokens
|
|
3303
|
+
* And SHORT_PRODUCT = ∏(PRICE^-(WEIGHT/100)) for short tokens
|
|
3304
|
+
*
|
|
3305
|
+
* Optimized version that uses Map lookups instead of Array.find()
|
|
3306
|
+
*/
|
|
3307
|
+
const calculateWeightedRatio = (longTokens, shortTokens, candleLookups, timestamp, priceType) => {
|
|
3308
|
+
let longProduct = 1;
|
|
3309
|
+
let shortProduct = 1;
|
|
3310
|
+
// Long side: PRICE^(WEIGHT/100)
|
|
3311
|
+
for (const token of longTokens) {
|
|
3312
|
+
const lookup = candleLookups[token.symbol];
|
|
3313
|
+
const candle = lookup === null || lookup === void 0 ? void 0 : lookup.get(timestamp);
|
|
3314
|
+
if (candle) {
|
|
3315
|
+
const price = parseFloat(candle[priceType]);
|
|
3316
|
+
if (price > 0) {
|
|
3317
|
+
const weightFactor = token.weight / 100;
|
|
3318
|
+
longProduct *= Math.pow(price, weightFactor);
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
else {
|
|
3322
|
+
return 0; // Missing data
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
// Short side: PRICE^-(WEIGHT/100)
|
|
3326
|
+
for (const token of shortTokens) {
|
|
3327
|
+
const lookup = candleLookups[token.symbol];
|
|
3328
|
+
const candle = lookup === null || lookup === void 0 ? void 0 : lookup.get(timestamp);
|
|
3329
|
+
if (candle) {
|
|
3330
|
+
const price = parseFloat(candle[priceType]);
|
|
3331
|
+
if (price > 0) {
|
|
3332
|
+
const weightFactor = token.weight / 100;
|
|
3333
|
+
shortProduct *= Math.pow(price, -weightFactor);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
else {
|
|
3337
|
+
return 0; // Missing data
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
return longProduct * shortProduct;
|
|
3341
|
+
};
|
|
3342
|
+
/**
|
|
3343
|
+
* Get all unique timestamps where ALL required symbols have data
|
|
3344
|
+
* Optimized version that uses Map lookups
|
|
3345
|
+
*/
|
|
3346
|
+
const getCompleteTimestamps = (candleLookups, requiredSymbols) => {
|
|
3347
|
+
var _a;
|
|
3348
|
+
if (requiredSymbols.length === 0)
|
|
3349
|
+
return [];
|
|
3350
|
+
// Choose the smallest timestamp set to minimize checks
|
|
3351
|
+
let baseSymbol;
|
|
3352
|
+
let baseLookup;
|
|
3353
|
+
let baseSize = Infinity;
|
|
3354
|
+
for (const symbol of requiredSymbols) {
|
|
3355
|
+
const lookup = candleLookups[symbol];
|
|
3356
|
+
const size = (_a = lookup === null || lookup === void 0 ? void 0 : lookup.size) !== null && _a !== void 0 ? _a : 0;
|
|
3357
|
+
if (size === 0)
|
|
3358
|
+
return []; // If any required symbol has no data, intersection is empty
|
|
3359
|
+
if (size < baseSize) {
|
|
3360
|
+
baseSize = size;
|
|
3361
|
+
baseSymbol = symbol;
|
|
3362
|
+
baseLookup = lookup;
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
if (!baseLookup || !baseSymbol)
|
|
3366
|
+
return [];
|
|
3367
|
+
const result = [];
|
|
3368
|
+
for (const timestamp of baseLookup.keys()) {
|
|
3369
|
+
let ok = true;
|
|
3370
|
+
for (const symbol of requiredSymbols) {
|
|
3371
|
+
if (symbol === baseSymbol)
|
|
3372
|
+
continue;
|
|
3373
|
+
const lookup = candleLookups[symbol];
|
|
3374
|
+
if (!lookup || !lookup.has(timestamp)) {
|
|
3375
|
+
ok = false;
|
|
3376
|
+
break;
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
if (ok)
|
|
3380
|
+
result.push(timestamp);
|
|
3381
|
+
}
|
|
3382
|
+
// Ensure deterministic ordering regardless of input
|
|
3383
|
+
result.sort((a, b) => a - b);
|
|
3384
|
+
return result;
|
|
3385
|
+
};
|
|
3386
|
+
/**
|
|
3387
|
+
* Compute basket candles from individual token candles using weighted ratios
|
|
3388
|
+
* Optimized version that creates lookup maps once and reuses them
|
|
3389
|
+
*/
|
|
3390
|
+
const computeBasketCandles = (longTokens, shortTokens, tokenCandles) => {
|
|
3391
|
+
var _a, _b;
|
|
3392
|
+
if (longTokens.length === 0 || shortTokens.length === 0) {
|
|
3393
|
+
return [];
|
|
3394
|
+
}
|
|
3395
|
+
// Create efficient lookup maps once
|
|
3396
|
+
const candleLookups = createCandleLookups(tokenCandles);
|
|
3397
|
+
const allSymbols = [...longTokens, ...shortTokens].map(t => t.symbol);
|
|
3398
|
+
const completeTimestamps = getCompleteTimestamps(candleLookups, allSymbols);
|
|
3399
|
+
const basketCandles = [];
|
|
3400
|
+
for (const timestamp of completeTimestamps) {
|
|
3401
|
+
// Compute all OHLC products in a single pass per side
|
|
3402
|
+
let longOpen = 1, longHigh = 1, longLow = 1, longClose = 1;
|
|
3403
|
+
let shortOpen = 1, shortHigh = 1, shortLow = 1, shortClose = 1;
|
|
3404
|
+
let totalVolume = 0;
|
|
3405
|
+
let totalTrades = 0;
|
|
3406
|
+
let candleDuration = 0;
|
|
3407
|
+
let missing = false;
|
|
3408
|
+
// Accumulate volume/trades and compute long side contributions
|
|
3409
|
+
for (const token of longTokens) {
|
|
3410
|
+
const candle = (_a = candleLookups[token.symbol]) === null || _a === void 0 ? void 0 : _a.get(timestamp);
|
|
3411
|
+
if (!candle) {
|
|
3412
|
+
missing = true;
|
|
3413
|
+
break;
|
|
3414
|
+
}
|
|
3415
|
+
const weightFactor = token.weight / 100;
|
|
3416
|
+
const o = parseFloat(candle.o);
|
|
3417
|
+
const h = parseFloat(candle.h);
|
|
3418
|
+
const l = parseFloat(candle.l);
|
|
3419
|
+
const c = parseFloat(candle.c);
|
|
3420
|
+
if (!(o > 0 && h > 0 && l > 0 && c > 0)) {
|
|
3421
|
+
missing = true;
|
|
3422
|
+
break;
|
|
3423
|
+
}
|
|
3424
|
+
longOpen *= Math.pow(o, weightFactor);
|
|
3425
|
+
longHigh *= Math.pow(h, weightFactor);
|
|
3426
|
+
longLow *= Math.pow(l, weightFactor);
|
|
3427
|
+
longClose *= Math.pow(c, weightFactor);
|
|
3428
|
+
totalVolume += parseFloat(candle.v);
|
|
3429
|
+
totalTrades += candle.n;
|
|
3430
|
+
if (candleDuration === 0)
|
|
3431
|
+
candleDuration = candle.T - candle.t;
|
|
3432
|
+
}
|
|
3433
|
+
if (missing)
|
|
3434
|
+
continue;
|
|
3435
|
+
// Short side contributions (negative exponent)
|
|
3436
|
+
for (const token of shortTokens) {
|
|
3437
|
+
const candle = (_b = candleLookups[token.symbol]) === null || _b === void 0 ? void 0 : _b.get(timestamp);
|
|
3438
|
+
if (!candle) {
|
|
3439
|
+
missing = true;
|
|
3440
|
+
break;
|
|
3441
|
+
}
|
|
3442
|
+
const weightFactor = -(token.weight / 100);
|
|
3443
|
+
const o = parseFloat(candle.o);
|
|
3444
|
+
const h = parseFloat(candle.h);
|
|
3445
|
+
const l = parseFloat(candle.l);
|
|
3446
|
+
const c = parseFloat(candle.c);
|
|
3447
|
+
if (!(o > 0 && h > 0 && l > 0 && c > 0)) {
|
|
3448
|
+
missing = true;
|
|
3449
|
+
break;
|
|
3450
|
+
}
|
|
3451
|
+
shortOpen *= Math.pow(o, weightFactor);
|
|
3452
|
+
shortHigh *= Math.pow(h, weightFactor);
|
|
3453
|
+
shortLow *= Math.pow(l, weightFactor);
|
|
3454
|
+
shortClose *= Math.pow(c, weightFactor);
|
|
3455
|
+
totalVolume += parseFloat(candle.v);
|
|
3456
|
+
totalTrades += candle.n;
|
|
3457
|
+
if (candleDuration === 0)
|
|
3458
|
+
candleDuration = candle.T - candle.t;
|
|
3459
|
+
}
|
|
3460
|
+
if (missing)
|
|
3461
|
+
continue;
|
|
3462
|
+
basketCandles.push({
|
|
3463
|
+
t: timestamp,
|
|
3464
|
+
T: timestamp + candleDuration,
|
|
3465
|
+
o: longOpen * shortOpen,
|
|
3466
|
+
h: longHigh * shortHigh,
|
|
3467
|
+
l: longLow * shortLow,
|
|
3468
|
+
c: longClose * shortClose,
|
|
3469
|
+
v: totalVolume,
|
|
3470
|
+
n: totalTrades,
|
|
3471
|
+
});
|
|
3472
|
+
}
|
|
3473
|
+
return basketCandles;
|
|
3474
|
+
};
|
|
3475
|
+
|
|
3476
|
+
/**
|
|
3477
|
+
* Composes historical price fetching with basket candle computation.
|
|
3478
|
+
* - Listens to `longTokens` and `shortTokens` from user selection.
|
|
3479
|
+
* - Uses `fetchHistoricalPriceData` to retrieve token candles for the range.
|
|
3480
|
+
* - Computes and returns weighted basket candles via `computeBasketCandles`.
|
|
3481
|
+
*/
|
|
3482
|
+
const useBasketCandles = () => {
|
|
3483
|
+
const longTokens = useUserSelection$1((state) => state.longTokens);
|
|
3484
|
+
const shortTokens = useUserSelection$1((state) => state.shortTokens);
|
|
3485
|
+
const { fetchHistoricalPriceData, isLoading: tokenLoading } = useHistoricalPriceData();
|
|
3486
|
+
const fetchBasketCandles = useCallback(async (startTime, endTime) => {
|
|
3487
|
+
const tokenCandles = await fetchHistoricalPriceData(startTime, endTime);
|
|
3488
|
+
const basket = computeBasketCandles(longTokens, shortTokens, tokenCandles);
|
|
3489
|
+
return basket;
|
|
3490
|
+
}, [fetchHistoricalPriceData, longTokens, shortTokens]);
|
|
3491
|
+
// Aggregate loading across selected tokens via underlying hook
|
|
3492
|
+
const isLoading = tokenLoading();
|
|
3493
|
+
return {
|
|
3494
|
+
fetchBasketCandles,
|
|
3495
|
+
isLoading,
|
|
3496
|
+
};
|
|
3497
|
+
};
|
|
3498
|
+
|
|
3499
|
+
/**
|
|
3500
|
+
* Detects conflicts between selected tokens and existing positions
|
|
3501
|
+
*/
|
|
3502
|
+
class ConflictDetector {
|
|
3503
|
+
/**
|
|
3504
|
+
* Detects conflicts between token selections and open positions
|
|
3505
|
+
* @param longTokens - Selected long tokens
|
|
3506
|
+
* @param shortTokens - Selected short tokens
|
|
3507
|
+
* @param openPositions - Current open positions from API
|
|
3508
|
+
* @returns Array of detected conflicts
|
|
3509
|
+
*/
|
|
3510
|
+
static detectConflicts(longTokens, shortTokens, openPositions) {
|
|
3511
|
+
const detectedConflicts = [];
|
|
3512
|
+
if (!openPositions) {
|
|
3513
|
+
return detectedConflicts;
|
|
3514
|
+
}
|
|
3515
|
+
// Check long tokens against existing short positions
|
|
3516
|
+
longTokens.forEach((token) => {
|
|
3517
|
+
const existingShortPosition = openPositions.find((pos) => {
|
|
3518
|
+
var _a;
|
|
3519
|
+
// Check multiple possible property names and side values
|
|
3520
|
+
const symbol = pos.coin || pos.symbol || pos.asset;
|
|
3521
|
+
const side = (_a = pos.side) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
3522
|
+
return symbol === token.symbol && (side === 'short' || side === 'sell');
|
|
3523
|
+
});
|
|
3524
|
+
if (existingShortPosition) {
|
|
3525
|
+
detectedConflicts.push({
|
|
3526
|
+
symbol: token.symbol,
|
|
3527
|
+
conflictType: 'short',
|
|
3528
|
+
conflictMessage: `${token.symbol} Long conflicts with existing ${token.symbol} Short position`
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
});
|
|
3532
|
+
// Check short tokens against existing long positions
|
|
3533
|
+
shortTokens.forEach((token) => {
|
|
3534
|
+
const existingLongPosition = openPositions.find((pos) => {
|
|
3535
|
+
var _a;
|
|
3536
|
+
// Check multiple possible property names and side values
|
|
3537
|
+
const symbol = pos.coin || pos.symbol || pos.asset;
|
|
3538
|
+
const side = (_a = pos.side) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
3539
|
+
return symbol === token.symbol && (side === 'long' || side === 'buy');
|
|
3540
|
+
});
|
|
3541
|
+
if (existingLongPosition) {
|
|
3542
|
+
detectedConflicts.push({
|
|
3543
|
+
symbol: token.symbol,
|
|
3544
|
+
conflictType: 'long',
|
|
3545
|
+
conflictMessage: `${token.symbol} Short conflicts with existing ${token.symbol} Long position`
|
|
3546
|
+
});
|
|
3547
|
+
}
|
|
3548
|
+
});
|
|
3549
|
+
return detectedConflicts;
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
export { AccountSummaryCalculator, ConflictDetector, PearHyperliquidClient, PearHyperliquidProvider, PearMigrationSDK, TokenMetadataExtractor, calculateWeightedRatio, computeBasketCandles, createCandleLookups, PearHyperliquidClient as default, getCompleteTimestamps, useAccountSummary, useAddress, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMigrationSDK, useOpenOrders, useOpenPositions, usePearHyperliquidClient, useTokenSelectionMetadata, useTradeHistories, useUserSelection, useWebData };
|