@agg-build/hooks 4.17.2 → 4.18.2
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/{chunk-IVUHIMRY.mjs → chunk-5B2F3GMC.mjs} +1 -1
- package/dist/{chunk-KQ5TOPNY.mjs → chunk-ESDA4NZI.mjs} +687 -604
- package/dist/{chunk-BBAKQDOH.mjs → chunk-SBGLJDPJ.mjs} +1 -1
- package/dist/deposit.js +128 -2
- package/dist/deposit.mjs +2 -2
- package/dist/index.d.mts +983 -26
- package/dist/index.d.ts +983 -26
- package/dist/index.js +2478 -1283
- package/dist/index.mjs +1487 -387
- package/dist/withdraw.d.mts +5 -0
- package/dist/withdraw.d.ts +5 -0
- package/dist/withdraw.js +132 -5
- package/dist/withdraw.mjs +2 -2
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useRampQuotes,
|
|
3
3
|
useRampSession
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SBGLJDPJ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
useWithdrawEstimate,
|
|
7
7
|
useWithdrawFlow,
|
|
8
8
|
useWithdrawPreview,
|
|
9
9
|
useWithdrawalLifecycle
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5B2F3GMC.mjs";
|
|
11
11
|
import {
|
|
12
12
|
AggAuthContext,
|
|
13
13
|
AggBalanceProvider,
|
|
@@ -26,20 +26,17 @@ import {
|
|
|
26
26
|
Venue,
|
|
27
27
|
__async,
|
|
28
28
|
__objRest,
|
|
29
|
+
__pow,
|
|
29
30
|
__spreadProps,
|
|
30
31
|
__spreadValues,
|
|
31
32
|
appConfigQueryKey,
|
|
32
|
-
applyOrderbookDepth,
|
|
33
33
|
computeClosedPositionTotals,
|
|
34
|
-
createMarketChartData,
|
|
35
34
|
createMarketLiveState,
|
|
36
|
-
createMarketOrderbookDataFromState,
|
|
37
|
-
createMarketOrderbookDataFromVenueOrderbooks,
|
|
38
35
|
defaultAggUiConfig,
|
|
39
36
|
executionKeys,
|
|
40
37
|
getBuilder,
|
|
41
38
|
getDepositAddress,
|
|
42
|
-
|
|
39
|
+
getMarketLiveStore,
|
|
43
40
|
getOrCreateBuilder,
|
|
44
41
|
getWalletAddressFromUserProfile,
|
|
45
42
|
invalidateBalanceQueries,
|
|
@@ -48,8 +45,6 @@ import {
|
|
|
48
45
|
invalidateUserClaimState,
|
|
49
46
|
invalidateUserMoneyState,
|
|
50
47
|
marketDataKeys,
|
|
51
|
-
marketOrderbookDataToResponse,
|
|
52
|
-
mergeMarketChartData,
|
|
53
48
|
optimizedImageUrl,
|
|
54
49
|
parseEmail,
|
|
55
50
|
parseEmailStrict,
|
|
@@ -60,6 +55,7 @@ import {
|
|
|
60
55
|
resolveMarketWinningOutcome,
|
|
61
56
|
resolveOrderEligibility,
|
|
62
57
|
resolveTradingStateKind,
|
|
58
|
+
retinaImageUrl,
|
|
63
59
|
sortVenues,
|
|
64
60
|
tradingReducer,
|
|
65
61
|
useAggAuthContext,
|
|
@@ -82,6 +78,7 @@ import {
|
|
|
82
78
|
useExecuteManaged,
|
|
83
79
|
useExecutionProgress,
|
|
84
80
|
useLabels,
|
|
81
|
+
useLiveStates,
|
|
85
82
|
useManagedBalances,
|
|
86
83
|
useOnBalanceUpdate,
|
|
87
84
|
useOnOrderEvent,
|
|
@@ -101,10 +98,10 @@ import {
|
|
|
101
98
|
useSyncBalances,
|
|
102
99
|
useWithdrawManaged,
|
|
103
100
|
userActivityQueryKeys
|
|
104
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-ESDA4NZI.mjs";
|
|
105
102
|
|
|
106
103
|
// src/index.ts
|
|
107
|
-
import { QueryClient as QueryClient4, QueryClientProvider, useQueryClient as
|
|
104
|
+
import { QueryClient as QueryClient4, QueryClientProvider, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
|
|
108
105
|
import { TurnstileChallengeError } from "@agg-build/sdk";
|
|
109
106
|
|
|
110
107
|
// src/use-geo-block.ts
|
|
@@ -170,9 +167,113 @@ var useVenueKeyStatus = (venue, enabled = true) => {
|
|
|
170
167
|
});
|
|
171
168
|
};
|
|
172
169
|
|
|
170
|
+
// src/use-hosted-venue-account.ts
|
|
171
|
+
import { useEffect, useRef } from "react";
|
|
172
|
+
import { useMutation, useQuery as useQuery2, useQueryClient } from "@tanstack/react-query";
|
|
173
|
+
var hostedVenueAccountQueryKeys = {
|
|
174
|
+
all: ["agg", "hosted-venue-account"],
|
|
175
|
+
account: (venue, userId, mode) => ["agg", "hosted-venue-account", venue, userId, mode]
|
|
176
|
+
};
|
|
177
|
+
function useHostedVenueAccount(venue, enabled = true) {
|
|
178
|
+
var _a;
|
|
179
|
+
const client = useAggClient();
|
|
180
|
+
const { user, isAuthenticated } = useAggAuthContext();
|
|
181
|
+
const { executionMode, isResolving } = useResolvedExecutionMode();
|
|
182
|
+
const queryClient = useQueryClient();
|
|
183
|
+
const userId = (_a = user == null ? void 0 : user.id) != null ? _a : null;
|
|
184
|
+
const permitted = enabled && isAuthenticated && userId !== null && !isResolving && executionMode === "live";
|
|
185
|
+
const queryKey = hostedVenueAccountQueryKeys.account(venue, userId, executionMode);
|
|
186
|
+
const session = useRef({ client, userId, executionMode, permitted });
|
|
187
|
+
session.current = { client, userId, executionMode, permitted };
|
|
188
|
+
const assertSession = () => {
|
|
189
|
+
const current = session.current;
|
|
190
|
+
if (!permitted || !current.permitted || current.client !== client || current.userId !== userId || current.executionMode !== executionMode)
|
|
191
|
+
throw new Error("Hosted custody is unavailable for this session");
|
|
192
|
+
};
|
|
193
|
+
const account = useQuery2({
|
|
194
|
+
queryKey,
|
|
195
|
+
queryFn: () => {
|
|
196
|
+
assertSession();
|
|
197
|
+
return client.getHostedVenueAccount(venue, { mode: executionMode });
|
|
198
|
+
},
|
|
199
|
+
enabled: permitted,
|
|
200
|
+
staleTime: 3e3,
|
|
201
|
+
refetchInterval: permitted ? 5e3 : false,
|
|
202
|
+
refetchIntervalInBackground: false,
|
|
203
|
+
retry: false
|
|
204
|
+
});
|
|
205
|
+
const provision = useMutation({
|
|
206
|
+
mutationFn: (request2) => request2.run(),
|
|
207
|
+
// Retain the dispatch-time user key even if the observer changes users.
|
|
208
|
+
onSuccess: (result, request2) => {
|
|
209
|
+
queryClient.setQueryData(request2.queryKey, result);
|
|
210
|
+
invalidateBalanceQueries(queryClient);
|
|
211
|
+
},
|
|
212
|
+
retry: false
|
|
213
|
+
});
|
|
214
|
+
const { reset } = provision;
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
reset();
|
|
217
|
+
}, [userId, executionMode, reset]);
|
|
218
|
+
const request = () => ({
|
|
219
|
+
queryKey,
|
|
220
|
+
run: () => {
|
|
221
|
+
assertSession();
|
|
222
|
+
return client.provisionHostedVenueAccount(venue, { mode: "live" });
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
return {
|
|
226
|
+
account,
|
|
227
|
+
provision: __spreadProps(__spreadValues({}, provision), {
|
|
228
|
+
mutate: () => provision.mutate(request()),
|
|
229
|
+
mutateAsync: () => provision.mutateAsync(request())
|
|
230
|
+
}),
|
|
231
|
+
isAvailable: permitted
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// src/use-hosted-venue-activity.ts
|
|
236
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
237
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
238
|
+
function useHostedVenueActivity(venue, page = 0, enabled = true) {
|
|
239
|
+
var _a;
|
|
240
|
+
const client = useAggClient();
|
|
241
|
+
const { user, isAuthenticated } = useAggAuthContext();
|
|
242
|
+
const { executionMode, isResolving } = useResolvedExecutionMode();
|
|
243
|
+
const userId = (_a = user == null ? void 0 : user.id) != null ? _a : null;
|
|
244
|
+
const permitted = enabled && isAuthenticated && userId !== null && !isResolving && executionMode === "live" && Number.isInteger(page) && page >= 0 && page <= 9999;
|
|
245
|
+
const session = useRef2({ client, userId, executionMode, permitted });
|
|
246
|
+
session.current = { client, userId, executionMode, permitted };
|
|
247
|
+
const mounted = useRef2(true);
|
|
248
|
+
useEffect2(() => {
|
|
249
|
+
mounted.current = true;
|
|
250
|
+
return () => {
|
|
251
|
+
mounted.current = false;
|
|
252
|
+
};
|
|
253
|
+
}, []);
|
|
254
|
+
const assertSession = () => {
|
|
255
|
+
const current = session.current;
|
|
256
|
+
if (!mounted.current || !permitted || !current.permitted || current.client !== client || current.userId !== userId || current.executionMode !== executionMode)
|
|
257
|
+
throw new Error("Hosted activity is unavailable for this session");
|
|
258
|
+
};
|
|
259
|
+
const activity = useQuery3({
|
|
260
|
+
queryKey: [...hostedVenueAccountQueryKeys.all, "activity", venue, userId, executionMode, page],
|
|
261
|
+
queryFn: () => __async(null, null, function* () {
|
|
262
|
+
assertSession();
|
|
263
|
+
const result = yield client.getHostedVenueActivity(venue, { mode: executionMode, page });
|
|
264
|
+
assertSession();
|
|
265
|
+
return result;
|
|
266
|
+
}),
|
|
267
|
+
enabled: permitted,
|
|
268
|
+
staleTime: 3e3,
|
|
269
|
+
retry: false
|
|
270
|
+
});
|
|
271
|
+
return { activity, isAvailable: permitted };
|
|
272
|
+
}
|
|
273
|
+
|
|
173
274
|
// src/use-shared-kyc.ts
|
|
174
275
|
import { useCallback } from "react";
|
|
175
|
-
import { useQuery as
|
|
276
|
+
import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
176
277
|
var sharedKycQueryKeys = {
|
|
177
278
|
status: (userId) => ["agg", "shared-kyc", userId]
|
|
178
279
|
};
|
|
@@ -181,7 +282,7 @@ var useSharedKyc = () => {
|
|
|
181
282
|
const client = useAggClient();
|
|
182
283
|
const { isAuthenticated, user } = useAggAuthContext();
|
|
183
284
|
const userId = (_a = user == null ? void 0 : user.id) != null ? _a : null;
|
|
184
|
-
const query =
|
|
285
|
+
const query = useQuery4({
|
|
185
286
|
queryKey: sharedKycQueryKeys.status(userId),
|
|
186
287
|
queryFn: () => client.getSharedKycStatus(),
|
|
187
288
|
enabled: isAuthenticated && userId !== null,
|
|
@@ -340,10 +441,10 @@ function useCategoryChildren(options) {
|
|
|
340
441
|
}
|
|
341
442
|
|
|
342
443
|
// src/use-debounced-value.ts
|
|
343
|
-
import { useEffect, useState as useState2 } from "react";
|
|
444
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
344
445
|
function useDebouncedValue(value, delay) {
|
|
345
446
|
const [debouncedValue, setDebouncedValue] = useState2(value);
|
|
346
|
-
|
|
447
|
+
useEffect3(() => {
|
|
347
448
|
const timeoutId = window.setTimeout(() => {
|
|
348
449
|
setDebouncedValue(value);
|
|
349
450
|
}, delay);
|
|
@@ -364,11 +465,13 @@ function useExecutionOrders(options = {}) {
|
|
|
364
465
|
orderType,
|
|
365
466
|
orderId,
|
|
366
467
|
quoteId,
|
|
468
|
+
venueMarketIds,
|
|
367
469
|
mode,
|
|
368
470
|
limit = 50,
|
|
369
471
|
enabled = true,
|
|
370
472
|
refetchIntervalMs = false
|
|
371
473
|
} = options;
|
|
474
|
+
const venueMarketIdsKey = (venueMarketIds == null ? void 0 : venueMarketIds.length) ? [...new Set(venueMarketIds)].sort() : null;
|
|
372
475
|
const query = useInfiniteQuery2({
|
|
373
476
|
// quoteId + orderId are part of the cache key — different filters
|
|
374
477
|
// produce different result sets, so they have to vary the key.
|
|
@@ -377,16 +480,17 @@ function useExecutionOrders(options = {}) {
|
|
|
377
480
|
status != null ? status : "all",
|
|
378
481
|
quoteId != null ? quoteId : null,
|
|
379
482
|
orderId != null ? orderId : null,
|
|
483
|
+
...venueMarketIdsKey ? [{ venueMarketIds: venueMarketIdsKey }] : [],
|
|
380
484
|
...orderType ? [orderType] : [],
|
|
381
485
|
...mode ? [mode] : [],
|
|
382
486
|
limit
|
|
383
487
|
],
|
|
384
|
-
queryFn: ({ pageParam }) => client.getExecutionOrders(__spreadProps(__spreadValues({
|
|
488
|
+
queryFn: ({ pageParam }) => client.getExecutionOrders(__spreadProps(__spreadValues(__spreadValues({
|
|
385
489
|
status,
|
|
386
490
|
orderType,
|
|
387
491
|
orderId,
|
|
388
492
|
quoteId
|
|
389
|
-
}, mode ? { mode } : {}), {
|
|
493
|
+
}, venueMarketIdsKey ? { venueMarketIds: venueMarketIdsKey } : {}), mode ? { mode } : {}), {
|
|
390
494
|
limit,
|
|
391
495
|
cursor: pageParam
|
|
392
496
|
})),
|
|
@@ -406,6 +510,85 @@ function useExecutionOrders(options = {}) {
|
|
|
406
510
|
});
|
|
407
511
|
}
|
|
408
512
|
|
|
513
|
+
// src/use-execution-orders-for-markets.ts
|
|
514
|
+
import { useQueries as useQueries2 } from "@tanstack/react-query";
|
|
515
|
+
import { useMemo } from "react";
|
|
516
|
+
var MAX_ORDER_VENUE_MARKET_IDS_PER_REQUEST = 75;
|
|
517
|
+
var DEFAULT_PAGE_LIMIT = 100;
|
|
518
|
+
var DEFAULT_MAX_PAGES_PER_BATCH = 5;
|
|
519
|
+
var combineBatches = (results) => {
|
|
520
|
+
var _a, _b;
|
|
521
|
+
return {
|
|
522
|
+
orders: results.flatMap((result) => {
|
|
523
|
+
var _a2, _b2;
|
|
524
|
+
return (_b2 = (_a2 = result.data) == null ? void 0 : _a2.orders) != null ? _b2 : [];
|
|
525
|
+
}),
|
|
526
|
+
isLoading: results.some((result) => result.isLoading),
|
|
527
|
+
error: (_b = (_a = results.find((result) => result.error)) == null ? void 0 : _a.error) != null ? _b : null,
|
|
528
|
+
isTruncated: results.some((result) => {
|
|
529
|
+
var _a2;
|
|
530
|
+
return ((_a2 = result.data) == null ? void 0 : _a2.hasMore) === true;
|
|
531
|
+
})
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
var chunk = (items, size) => {
|
|
535
|
+
const chunks = [];
|
|
536
|
+
for (let index = 0; index < items.length; index += size) {
|
|
537
|
+
chunks.push(items.slice(index, index + size));
|
|
538
|
+
}
|
|
539
|
+
return chunks;
|
|
540
|
+
};
|
|
541
|
+
function useExecutionOrdersForMarkets({
|
|
542
|
+
venueMarketIds,
|
|
543
|
+
status,
|
|
544
|
+
orderType,
|
|
545
|
+
mode,
|
|
546
|
+
limit = DEFAULT_PAGE_LIMIT,
|
|
547
|
+
maxPagesPerBatch = DEFAULT_MAX_PAGES_PER_BATCH,
|
|
548
|
+
enabled = true
|
|
549
|
+
}) {
|
|
550
|
+
const client = useAggClient();
|
|
551
|
+
const batchKey = [...new Set(venueMarketIds)].sort().join(",");
|
|
552
|
+
const batches = useMemo(
|
|
553
|
+
() => batchKey ? chunk(batchKey.split(","), MAX_ORDER_VENUE_MARKET_IDS_PER_REQUEST) : [],
|
|
554
|
+
[batchKey]
|
|
555
|
+
);
|
|
556
|
+
return useQueries2({
|
|
557
|
+
combine: combineBatches,
|
|
558
|
+
queries: batches.map((batchVenueMarketIds) => ({
|
|
559
|
+
queryKey: [
|
|
560
|
+
"execution-orders",
|
|
561
|
+
"by-markets",
|
|
562
|
+
batchVenueMarketIds,
|
|
563
|
+
status != null ? status : "all",
|
|
564
|
+
orderType != null ? orderType : null,
|
|
565
|
+
mode != null ? mode : null,
|
|
566
|
+
limit,
|
|
567
|
+
maxPagesPerBatch
|
|
568
|
+
],
|
|
569
|
+
queryFn: () => __async(null, null, function* () {
|
|
570
|
+
var _a;
|
|
571
|
+
const orders = [];
|
|
572
|
+
let cursor;
|
|
573
|
+
for (let page = 0; page < maxPagesPerBatch; page += 1) {
|
|
574
|
+
const response = yield client.getExecutionOrders(__spreadValues(__spreadProps(__spreadValues({
|
|
575
|
+
venueMarketIds: batchVenueMarketIds,
|
|
576
|
+
status,
|
|
577
|
+
orderType
|
|
578
|
+
}, mode ? { mode } : {}), {
|
|
579
|
+
limit
|
|
580
|
+
}), cursor ? { cursor } : {}));
|
|
581
|
+
orders.push(...response.data);
|
|
582
|
+
cursor = response.hasMore ? (_a = response.nextCursor) != null ? _a : void 0 : void 0;
|
|
583
|
+
if (!cursor) return { orders, hasMore: false };
|
|
584
|
+
}
|
|
585
|
+
return { orders, hasMore: true };
|
|
586
|
+
}),
|
|
587
|
+
enabled
|
|
588
|
+
}))
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
409
592
|
// src/use-user-activity.ts
|
|
410
593
|
import { keepPreviousData, useInfiniteQuery as useInfiniteQuery3 } from "@tanstack/react-query";
|
|
411
594
|
var DEFAULT_PENDING_REFETCH_INTERVAL_MS = 15e3;
|
|
@@ -532,17 +715,376 @@ function useExecutionPositions(options = {}) {
|
|
|
532
715
|
}
|
|
533
716
|
|
|
534
717
|
// src/use-live-candle-overlay.ts
|
|
535
|
-
import { useCallback as useCallback5, useMemo as
|
|
718
|
+
import { useCallback as useCallback5, useMemo as useMemo5 } from "react";
|
|
536
719
|
|
|
537
720
|
// src/use-live-candles.ts
|
|
538
|
-
import { useMemo as
|
|
721
|
+
import { useMemo as useMemo4 } from "react";
|
|
539
722
|
import { mergeCandles, mergeClosedCandles } from "@agg-build/sdk";
|
|
540
723
|
|
|
541
724
|
// src/use-market-chart.ts
|
|
542
|
-
import { keepPreviousData as keepPreviousData2, useQueries as
|
|
725
|
+
import { keepPreviousData as keepPreviousData2, useQueries as useQueries3, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
726
|
+
|
|
727
|
+
// src/read-retry.ts
|
|
728
|
+
import { isAggApiError } from "@agg-build/sdk";
|
|
729
|
+
import { isServer } from "@tanstack/react-query";
|
|
730
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
731
|
+
var hint = (error) => {
|
|
732
|
+
if (!isAggApiError(error)) return void 0;
|
|
733
|
+
const value = error.retryAfterMs;
|
|
734
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
735
|
+
};
|
|
736
|
+
function withReadRetry(options) {
|
|
737
|
+
return {
|
|
738
|
+
retry: (failureCount, error) => {
|
|
739
|
+
var _a, _b;
|
|
740
|
+
if (((_a = hint(error)) != null ? _a : 0) > MAX_TIMER_DELAY_MS) return false;
|
|
741
|
+
const retry = (_b = options.retry) != null ? _b : isServer ? 0 : 3;
|
|
742
|
+
return typeof retry === "function" ? retry(failureCount, error) : retry === true || typeof retry === "number" && failureCount < retry;
|
|
743
|
+
},
|
|
744
|
+
retryDelay: (attempt, error) => {
|
|
745
|
+
var _a, _b;
|
|
746
|
+
return (_b = hint(error)) != null ? _b : typeof options.retryDelay === "function" ? options.retryDelay(attempt, error) : (_a = options.retryDelay) != null ? _a : Math.min(1e3 * __pow(2, attempt), 3e4);
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/market-data/chart-cache.ts
|
|
752
|
+
var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
|
|
753
|
+
var getIntervalSeconds = (interval) => {
|
|
754
|
+
switch (interval) {
|
|
755
|
+
case "1m":
|
|
756
|
+
return 60;
|
|
757
|
+
case "5m":
|
|
758
|
+
return 5 * 60;
|
|
759
|
+
case "1h":
|
|
760
|
+
return 60 * 60;
|
|
761
|
+
case "1d":
|
|
762
|
+
return 24 * 60 * 60;
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
var resolveMaxLastUpdateTs = (venues) => {
|
|
766
|
+
let max = null;
|
|
767
|
+
for (const venueData of Object.values(venues)) {
|
|
768
|
+
if (venueData.lastUpdateTs != null && (max == null || venueData.lastUpdateTs > max)) {
|
|
769
|
+
max = venueData.lastUpdateTs;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return max;
|
|
773
|
+
};
|
|
774
|
+
var sortCandles = (candles) => {
|
|
775
|
+
return [...candles].sort((left, right) => left.time - right.time);
|
|
776
|
+
};
|
|
777
|
+
var createMarketChartData = (params) => {
|
|
778
|
+
var _a;
|
|
779
|
+
const candles = sortCandles(
|
|
780
|
+
params.response.data.map((candle) => __spreadProps(__spreadValues({
|
|
781
|
+
time: Math.floor(candle.t / 1e3),
|
|
782
|
+
open: candle.o,
|
|
783
|
+
high: candle.h,
|
|
784
|
+
low: candle.l,
|
|
785
|
+
close: candle.c
|
|
786
|
+
}, Number.isFinite(candle.mean) ? { mean: candle.mean } : {}), {
|
|
787
|
+
volume: candle.v,
|
|
788
|
+
source: "rest"
|
|
789
|
+
}))
|
|
790
|
+
);
|
|
791
|
+
const lastCandle = candles[candles.length - 1];
|
|
792
|
+
const lastUpdateTs = (_a = lastCandle == null ? void 0 : lastCandle.time) != null ? _a : null;
|
|
793
|
+
const venues = {
|
|
794
|
+
[params.response.venue]: {
|
|
795
|
+
venue: params.response.venue,
|
|
796
|
+
outcomeIds: [params.response.venueMarketOutcomeId],
|
|
797
|
+
candles,
|
|
798
|
+
liveCandle: null,
|
|
799
|
+
lineValue: lastCandle == null ? void 0 : lastCandle.close,
|
|
800
|
+
lastTrade: null,
|
|
801
|
+
lastUpdateTs
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
return {
|
|
805
|
+
marketId: params.marketId,
|
|
806
|
+
delivery: params.response.meta,
|
|
807
|
+
outcomeIds: [params.response.venueMarketOutcomeId],
|
|
808
|
+
primaryVenue: params.response.venue,
|
|
809
|
+
interval: params.interval,
|
|
810
|
+
startTs: params.startTs,
|
|
811
|
+
endTs: params.endTs,
|
|
812
|
+
venues,
|
|
813
|
+
lastUpdateTs
|
|
814
|
+
};
|
|
815
|
+
};
|
|
816
|
+
var mergeMarketChartData = (params) => {
|
|
817
|
+
var _a, _b, _c, _d, _e;
|
|
818
|
+
if (params.datasets.length === 0) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
const primaryVenue = (_b = (_a = params.datasets[0]) == null ? void 0 : _a.primaryVenue) != null ? _b : "aggregate";
|
|
822
|
+
const outcomeIds = Array.from(
|
|
823
|
+
new Set(
|
|
824
|
+
params.datasets.flatMap((dataset) => {
|
|
825
|
+
return dataset.outcomeIds.length > 0 ? dataset.outcomeIds : [dataset.marketId];
|
|
826
|
+
})
|
|
827
|
+
)
|
|
828
|
+
);
|
|
829
|
+
const venues = params.datasets.reduce((acc, dataset) => {
|
|
830
|
+
for (const [venue, venueData] of Object.entries(dataset.venues)) {
|
|
831
|
+
const existingVenueData = acc[venue];
|
|
832
|
+
acc[venue] = existingVenueData ? __spreadProps(__spreadValues({}, venueData), {
|
|
833
|
+
outcomeIds: Array.from(
|
|
834
|
+
/* @__PURE__ */ new Set([...existingVenueData.outcomeIds, ...venueData.outcomeIds])
|
|
835
|
+
)
|
|
836
|
+
}) : venueData;
|
|
837
|
+
}
|
|
838
|
+
return acc;
|
|
839
|
+
}, {});
|
|
840
|
+
return {
|
|
841
|
+
marketId: params.marketId,
|
|
842
|
+
delivery: (_e = (_c = params.datasets.find((dataset) => dataset.marketId === params.marketId)) == null ? void 0 : _c.delivery) != null ? _e : (_d = params.datasets[0]) == null ? void 0 : _d.delivery,
|
|
843
|
+
outcomeIds,
|
|
844
|
+
primaryVenue,
|
|
845
|
+
interval: params.interval,
|
|
846
|
+
startTs: params.startTs,
|
|
847
|
+
endTs: params.endTs,
|
|
848
|
+
venues,
|
|
849
|
+
lastUpdateTs: resolveMaxLastUpdateTs(venues)
|
|
850
|
+
};
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// src/market-data/chart-retry-gate.ts
|
|
854
|
+
import { isAggApiError as isAggApiError3 } from "@agg-build/sdk";
|
|
855
|
+
|
|
856
|
+
// src/market-data/chart-history.ts
|
|
857
|
+
import {
|
|
858
|
+
loadImmutableHistory,
|
|
859
|
+
isAggApiError as isAggApiError2
|
|
860
|
+
} from "@agg-build/sdk";
|
|
861
|
+
var ChartDeliveryError = class extends Error {
|
|
862
|
+
constructor(state, retryAfterMs) {
|
|
863
|
+
super(`Chart delivery ${state}`);
|
|
864
|
+
this.state = state;
|
|
865
|
+
this.retryAfterMs = retryAfterMs;
|
|
866
|
+
this.name = "ChartDeliveryError";
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
var usable = (response) => {
|
|
870
|
+
var _a;
|
|
871
|
+
if (response.data.length === 0 && ((_a = response.meta) == null ? void 0 : _a.state) && response.meta.state !== "empty")
|
|
872
|
+
throw new ChartDeliveryError(response.meta.state, response.meta.retryAfterMs);
|
|
873
|
+
return response;
|
|
874
|
+
};
|
|
875
|
+
var withActualFreshness = (response) => {
|
|
876
|
+
var _a, _b;
|
|
877
|
+
const serverTime = Number.isFinite(response.meta.serverTime) ? response.meta.serverTime : Date.now();
|
|
878
|
+
const lastBarOpenTime = (_b = (_a = response.data.at(-1)) == null ? void 0 : _a.t) != null ? _b : null;
|
|
879
|
+
return __spreadProps(__spreadValues({}, response), {
|
|
880
|
+
meta: __spreadProps(__spreadValues({}, response.meta), {
|
|
881
|
+
serverTime,
|
|
882
|
+
lastBarOpenTime,
|
|
883
|
+
staleSeconds: lastBarOpenTime == null ? null : Math.max(0, (serverTime - lastBarOpenTime) / 1e3)
|
|
884
|
+
})
|
|
885
|
+
});
|
|
886
|
+
};
|
|
887
|
+
function fetchChartHistory(client, socket, request, signal, onInitial) {
|
|
888
|
+
return __async(this, null, function* () {
|
|
889
|
+
var _a, _b, _c;
|
|
890
|
+
const readBars = (params) => __async(null, null, function* () {
|
|
891
|
+
const response = yield client.getChartBars(params, __spreadValues({
|
|
892
|
+
signal
|
|
893
|
+
}, socket ? { decode: (text) => socket.decodeHistory(text) } : {}));
|
|
894
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
895
|
+
if (response.venueMarketOutcomeId !== request.venueMarketOutcomeId)
|
|
896
|
+
throw new Error("Chart history identity mismatch");
|
|
897
|
+
return response;
|
|
898
|
+
});
|
|
899
|
+
if (!client.preferImmutableHistory) return usable(yield readBars(request));
|
|
900
|
+
let verified;
|
|
901
|
+
try {
|
|
902
|
+
const manifest2 = yield client.getChartHistoryManifest(request, { signal });
|
|
903
|
+
if (manifest2.venueMarketOutcomeId !== request.venueMarketOutcomeId)
|
|
904
|
+
throw new Error("Chart manifest identity mismatch");
|
|
905
|
+
if (manifest2.meta.complete) {
|
|
906
|
+
const history2 = yield socket ? socket.loadHistory(manifest2, { signal }) : loadImmutableHistory({ manifest: manifest2, signal });
|
|
907
|
+
verified = {
|
|
908
|
+
manifest: manifest2,
|
|
909
|
+
history: history2.filter(
|
|
910
|
+
(bar) => (request.from == null || bar.t >= request.from) && bar.t < request.to
|
|
911
|
+
)
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
} catch (error) {
|
|
915
|
+
if ((signal == null ? void 0 : signal.aborted) || isAggApiError2(error) && (error.status === 429 || error.status === 503))
|
|
916
|
+
throw error;
|
|
917
|
+
}
|
|
918
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
919
|
+
if (!verified) return usable(yield readBars(request));
|
|
920
|
+
const { manifest, history } = verified;
|
|
921
|
+
const fullyCovered = manifest.finalizedThrough >= request.to;
|
|
922
|
+
const initial = withActualFreshness({
|
|
923
|
+
venueMarketOutcomeId: manifest.venueMarketOutcomeId,
|
|
924
|
+
venue: manifest.venue,
|
|
925
|
+
resolution: manifest.resolution,
|
|
926
|
+
data: history,
|
|
927
|
+
meta: __spreadProps(__spreadValues({}, manifest.meta), {
|
|
928
|
+
state: fullyCovered ? history.length ? "ready" : "empty" : "warming",
|
|
929
|
+
complete: fullyCovered
|
|
930
|
+
})
|
|
931
|
+
});
|
|
932
|
+
if (fullyCovered) return usable(initial);
|
|
933
|
+
if (history.length > 0) onInitial == null ? void 0 : onInitial(initial);
|
|
934
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
935
|
+
try {
|
|
936
|
+
const tail = yield readBars(__spreadProps(__spreadValues({}, request), {
|
|
937
|
+
resolution: manifest.resolution,
|
|
938
|
+
from: Math.max((_a = request.from) != null ? _a : 0, manifest.finalizedThrough),
|
|
939
|
+
countBack: void 0
|
|
940
|
+
}));
|
|
941
|
+
if (tail.venue !== manifest.venue || tail.resolution !== manifest.resolution)
|
|
942
|
+
throw new Error("Chart tail series mismatch");
|
|
943
|
+
const data = [
|
|
944
|
+
...history,
|
|
945
|
+
...tail.data.filter((bar) => bar.t >= manifest.finalizedThrough && bar.t < request.to)
|
|
946
|
+
];
|
|
947
|
+
const incomplete = tail.meta.complete === false || ["warming", "failed", "unsupported"].includes((_b = tail.meta.state) != null ? _b : "");
|
|
948
|
+
return usable(
|
|
949
|
+
withActualFreshness(__spreadProps(__spreadValues({}, tail), {
|
|
950
|
+
resolution: manifest.resolution,
|
|
951
|
+
data,
|
|
952
|
+
meta: __spreadProps(__spreadValues(__spreadValues({}, initial.meta), tail.meta), {
|
|
953
|
+
complete: !incomplete,
|
|
954
|
+
state: incomplete ? (_c = tail.meta.state) != null ? _c : "warming" : data.length ? "ready" : "empty"
|
|
955
|
+
})
|
|
956
|
+
}))
|
|
957
|
+
);
|
|
958
|
+
} catch (error) {
|
|
959
|
+
if (signal == null ? void 0 : signal.aborted) throw error;
|
|
960
|
+
return usable(
|
|
961
|
+
withActualFreshness(__spreadProps(__spreadValues({}, initial), {
|
|
962
|
+
meta: __spreadValues(__spreadProps(__spreadValues({}, initial.meta), {
|
|
963
|
+
state: error instanceof ChartDeliveryError ? error.state : "failed",
|
|
964
|
+
complete: false
|
|
965
|
+
}), (error instanceof ChartDeliveryError || isAggApiError2(error)) && error.retryAfterMs != null ? { retryAfterMs: error.retryAfterMs } : {})
|
|
966
|
+
}))
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// src/market-data/chart-retry-gate.ts
|
|
973
|
+
var MAX_TIMER_DELAY_MS2 = 2147483647;
|
|
974
|
+
var notBefore = /* @__PURE__ */ new WeakMap();
|
|
975
|
+
var validDelay = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
976
|
+
function record(query, delay) {
|
|
977
|
+
if (validDelay(delay) && delay > 0)
|
|
978
|
+
notBefore.set(query, Math.min(Number.MAX_SAFE_INTEGER, Date.now() + delay));
|
|
979
|
+
else notBefore.delete(query);
|
|
980
|
+
}
|
|
981
|
+
function chartRetryRemaining(query) {
|
|
982
|
+
var _a;
|
|
983
|
+
return Math.max(0, ((_a = notBefore.get(query)) != null ? _a : 0) - Date.now());
|
|
984
|
+
}
|
|
985
|
+
function chartRefetchInterval(query, interval) {
|
|
986
|
+
if (interval === false) return false;
|
|
987
|
+
const remaining = chartRetryRemaining(query);
|
|
988
|
+
return remaining > MAX_TIMER_DELAY_MS2 ? false : Math.max(interval, remaining);
|
|
989
|
+
}
|
|
990
|
+
function waitForDeadline(query, signal) {
|
|
991
|
+
return __async(this, null, function* () {
|
|
992
|
+
while (chartRetryRemaining(query) > 0) {
|
|
993
|
+
signal.throwIfAborted();
|
|
994
|
+
yield new Promise((resolve, reject) => {
|
|
995
|
+
const aborted = () => {
|
|
996
|
+
clearTimeout(timer);
|
|
997
|
+
signal.removeEventListener("abort", aborted);
|
|
998
|
+
reject(signal.reason);
|
|
999
|
+
};
|
|
1000
|
+
const timer = setTimeout(
|
|
1001
|
+
() => {
|
|
1002
|
+
signal.removeEventListener("abort", aborted);
|
|
1003
|
+
resolve();
|
|
1004
|
+
},
|
|
1005
|
+
Math.min(chartRetryRemaining(query), MAX_TIMER_DELAY_MS2)
|
|
1006
|
+
);
|
|
1007
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
1008
|
+
if (signal.aborted) aborted();
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
signal.throwIfAborted();
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
function runChartQuery(query, signal, load) {
|
|
1015
|
+
return __async(this, null, function* () {
|
|
1016
|
+
var _a;
|
|
1017
|
+
yield waitForDeadline(query, signal);
|
|
1018
|
+
try {
|
|
1019
|
+
const data = yield load();
|
|
1020
|
+
signal.throwIfAborted();
|
|
1021
|
+
const delivery = data.delivery;
|
|
1022
|
+
record(
|
|
1023
|
+
query,
|
|
1024
|
+
delivery && delivery.complete !== true && !["ready", "empty"].includes((_a = delivery.state) != null ? _a : "") ? delivery.retryAfterMs : void 0
|
|
1025
|
+
);
|
|
1026
|
+
return data;
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
if (!signal.aborted) {
|
|
1029
|
+
const delay = isAggApiError3(error) ? error.retryAfterMs : error instanceof ChartDeliveryError && validDelay(error.retryAfterMs) ? error.retryAfterMs : void 0;
|
|
1030
|
+
record(query, delay);
|
|
1031
|
+
}
|
|
1032
|
+
throw error;
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// src/market-data/chart-tail.ts
|
|
1038
|
+
var closedCaches = /* @__PURE__ */ new WeakMap();
|
|
1039
|
+
var toChart = (candle) => ({
|
|
1040
|
+
time: candle.openTime,
|
|
1041
|
+
open: candle.o,
|
|
1042
|
+
high: candle.h,
|
|
1043
|
+
low: candle.l,
|
|
1044
|
+
close: candle.c,
|
|
1045
|
+
volume: candle.v,
|
|
1046
|
+
source: "ws"
|
|
1047
|
+
});
|
|
1048
|
+
function overlayCandleTail(history, live, rolling) {
|
|
1049
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1050
|
+
const tail = (_a = live == null ? void 0 : live.candles) == null ? void 0 : _a[history.interval];
|
|
1051
|
+
const venue = history.venues[history.primaryVenue];
|
|
1052
|
+
if (!tail || !venue || !rolling && history.endTs != null && history.endTs < Date.now())
|
|
1053
|
+
return history;
|
|
1054
|
+
const last = (_c = (_b = venue.candles.at(-1)) == null ? void 0 : _b.time) != null ? _c : -Infinity;
|
|
1055
|
+
const closed = tail.closed.filter((candle) => candle.openTime > last);
|
|
1056
|
+
const key = closed.map((candle) => `${candle.openTime}:${candle.c}:${candle.v}`).join("|");
|
|
1057
|
+
let cached = closedCaches.get(history);
|
|
1058
|
+
if (!cached || cached.key !== key) {
|
|
1059
|
+
cached = {
|
|
1060
|
+
key,
|
|
1061
|
+
candles: closed.length ? [...venue.candles, ...closed.map(toChart)] : venue.candles
|
|
1062
|
+
};
|
|
1063
|
+
closedCaches.set(history, cached);
|
|
1064
|
+
}
|
|
1065
|
+
const forming = tail.forming && tail.forming.openTime >= last ? toChart(tail.forming) : null;
|
|
1066
|
+
const lastSourceTime = Math.max(
|
|
1067
|
+
(_e = (_d = live.orderbook) == null ? void 0 : _d.timestamp) != null ? _e : -Infinity,
|
|
1068
|
+
(_g = (_f = live.trades[0]) == null ? void 0 : _f.timestamp) != null ? _g : -Infinity,
|
|
1069
|
+
(_h = venue.lastUpdateTs) != null ? _h : -Infinity
|
|
1070
|
+
);
|
|
1071
|
+
const lastUpdateTs = Number.isFinite(lastSourceTime) ? lastSourceTime : null;
|
|
1072
|
+
return __spreadProps(__spreadValues({}, history), {
|
|
1073
|
+
lastUpdateTs,
|
|
1074
|
+
venues: __spreadProps(__spreadValues({}, history.venues), {
|
|
1075
|
+
[history.primaryVenue]: __spreadProps(__spreadValues({}, venue), {
|
|
1076
|
+
candles: cached.candles,
|
|
1077
|
+
liveCandle: forming,
|
|
1078
|
+
lineValue: (_i = forming == null ? void 0 : forming.close) != null ? _i : venue.lineValue,
|
|
1079
|
+
lastTrade: (_j = live.trades[0]) != null ? _j : venue.lastTrade,
|
|
1080
|
+
lastUpdateTs
|
|
1081
|
+
})
|
|
1082
|
+
})
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
543
1085
|
|
|
544
1086
|
// src/market-data/subscription.ts
|
|
545
|
-
import { useEffect as
|
|
1087
|
+
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
546
1088
|
function useMarketDataSubscription({
|
|
547
1089
|
marketId,
|
|
548
1090
|
additionalMarketIds,
|
|
@@ -551,7 +1093,7 @@ function useMarketDataSubscription({
|
|
|
551
1093
|
trades = false
|
|
552
1094
|
}) {
|
|
553
1095
|
const ws = useAggWebSocket();
|
|
554
|
-
const allIds =
|
|
1096
|
+
const allIds = useMemo2(() => {
|
|
555
1097
|
const ids = /* @__PURE__ */ new Set();
|
|
556
1098
|
if (marketId) ids.add(marketId);
|
|
557
1099
|
if (additionalMarketIds) {
|
|
@@ -562,7 +1104,7 @@ function useMarketDataSubscription({
|
|
|
562
1104
|
return [...ids];
|
|
563
1105
|
}, [marketId, additionalMarketIds]);
|
|
564
1106
|
const stableKey = allIds.join("|");
|
|
565
|
-
|
|
1107
|
+
useEffect4(() => {
|
|
566
1108
|
if (!ws || !allIds.length || !enabled || !orderbook && !trades) return;
|
|
567
1109
|
const unsubscribers = [];
|
|
568
1110
|
for (const id of allIds) {
|
|
@@ -584,9 +1126,11 @@ function useMarketDataSubscription({
|
|
|
584
1126
|
}
|
|
585
1127
|
|
|
586
1128
|
// src/use-market-chart.ts
|
|
587
|
-
function
|
|
588
|
-
var _a, _b
|
|
1129
|
+
function useMarketChartQueries(options) {
|
|
1130
|
+
var _a, _b;
|
|
589
1131
|
const client = useAggClient();
|
|
1132
|
+
const queryClient = useQueryClient2();
|
|
1133
|
+
const socket = useAggWebSocket();
|
|
590
1134
|
const isConnected = useAggWebSocketConnectionState();
|
|
591
1135
|
const {
|
|
592
1136
|
features: { enableLiveUpdates }
|
|
@@ -594,6 +1138,7 @@ function useMarketChart(options) {
|
|
|
594
1138
|
const {
|
|
595
1139
|
marketId,
|
|
596
1140
|
venueMarketIds,
|
|
1141
|
+
liveOutcomeIds,
|
|
597
1142
|
interval = "5m",
|
|
598
1143
|
startTs = null,
|
|
599
1144
|
endTs = null,
|
|
@@ -601,9 +1146,10 @@ function useMarketChart(options) {
|
|
|
601
1146
|
enabled = true,
|
|
602
1147
|
live,
|
|
603
1148
|
refetchIntervalMs = null,
|
|
1149
|
+
staleTimeMs,
|
|
604
1150
|
rangeKey
|
|
605
1151
|
} = options;
|
|
606
|
-
const resolvedRangeKey = rangeKey != null ? rangeKey : interval
|
|
1152
|
+
const resolvedRangeKey = rangeKey != null ? rangeKey : `${interval}:${startTs != null ? startTs : "count"}:${endTs != null ? endTs : "unset"}`;
|
|
607
1153
|
const liveEnabled = live != null ? live : enableLiveUpdates;
|
|
608
1154
|
const outcomeIds = (() => {
|
|
609
1155
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -617,72 +1163,197 @@ function useMarketChart(options) {
|
|
|
617
1163
|
})();
|
|
618
1164
|
const primaryOutcomeId = (_a = marketId != null ? marketId : venueMarketIds == null ? void 0 : venueMarketIds.find(Boolean)) != null ? _a : null;
|
|
619
1165
|
const isQueryEnabled = enabled && outcomeIds.length > 0 && endTs != null && (startTs != null || countBack != null);
|
|
1166
|
+
const subscribedIds = liveOutcomeIds ? outcomeIds.filter((id) => liveOutcomeIds.includes(id)) : outcomeIds;
|
|
1167
|
+
const subscribedPrimaryId = primaryOutcomeId && subscribedIds.includes(primaryOutcomeId) ? primaryOutcomeId : (_b = subscribedIds[0]) != null ? _b : null;
|
|
620
1168
|
useMarketDataSubscription({
|
|
621
|
-
marketId:
|
|
622
|
-
additionalMarketIds:
|
|
623
|
-
enabled: Boolean(isQueryEnabled && liveEnabled),
|
|
1169
|
+
marketId: subscribedPrimaryId,
|
|
1170
|
+
additionalMarketIds: subscribedIds.filter((id) => id !== subscribedPrimaryId),
|
|
1171
|
+
enabled: Boolean(isQueryEnabled && liveEnabled && subscribedIds.length > 0),
|
|
624
1172
|
orderbook: true,
|
|
625
1173
|
trades: true
|
|
626
1174
|
});
|
|
627
|
-
const queries =
|
|
628
|
-
queries: outcomeIds.map((outcomeId) => ({
|
|
1175
|
+
const queries = useQueries3({
|
|
1176
|
+
queries: outcomeIds.map((outcomeId) => __spreadProps(__spreadValues({
|
|
629
1177
|
// Cache key is intentionally time-free. The rolling window's
|
|
630
1178
|
// startTs/endTs advance on every bucket but the user expects the same
|
|
631
1179
|
// chart on revisit — see comment on `marketDataKeys.chart`. queryFn
|
|
632
1180
|
// closes over the current window so refetches still fetch fresh data.
|
|
633
1181
|
queryKey: marketDataKeys.chart(outcomeId, interval, resolvedRangeKey, countBack),
|
|
634
1182
|
queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
resolution: interval,
|
|
639
|
-
from: startTs != null ? startTs : void 0,
|
|
640
|
-
to: endTs,
|
|
641
|
-
countBack: countBack != null ? countBack : void 0
|
|
642
|
-
},
|
|
643
|
-
{ signal }
|
|
644
|
-
);
|
|
645
|
-
return createMarketChartData({
|
|
646
|
-
marketId: outcomeId,
|
|
647
|
-
interval,
|
|
648
|
-
startTs,
|
|
649
|
-
endTs,
|
|
650
|
-
response
|
|
1183
|
+
const owner = queryClient.getQueryCache().find({
|
|
1184
|
+
queryKey: marketDataKeys.chart(outcomeId, interval, resolvedRangeKey, countBack),
|
|
1185
|
+
exact: true
|
|
651
1186
|
});
|
|
1187
|
+
if (!owner) throw new Error("Chart query was removed before fetching");
|
|
1188
|
+
return runChartQuery(owner, signal, () => __async(null, null, function* () {
|
|
1189
|
+
var _a2;
|
|
1190
|
+
const response = yield fetchChartHistory(
|
|
1191
|
+
client,
|
|
1192
|
+
socket,
|
|
1193
|
+
{
|
|
1194
|
+
venueMarketOutcomeId: outcomeId,
|
|
1195
|
+
resolution: interval,
|
|
1196
|
+
from: startTs != null ? startTs : void 0,
|
|
1197
|
+
to: endTs,
|
|
1198
|
+
countBack: countBack != null ? countBack : void 0
|
|
1199
|
+
},
|
|
1200
|
+
signal,
|
|
1201
|
+
(initial) => {
|
|
1202
|
+
var _a3;
|
|
1203
|
+
if (signal.aborted) return;
|
|
1204
|
+
queryClient.setQueryData(
|
|
1205
|
+
marketDataKeys.chart(outcomeId, interval, resolvedRangeKey, countBack),
|
|
1206
|
+
createMarketChartData({
|
|
1207
|
+
marketId: outcomeId,
|
|
1208
|
+
interval: (_a3 = initial.resolution) != null ? _a3 : interval,
|
|
1209
|
+
startTs,
|
|
1210
|
+
endTs,
|
|
1211
|
+
response: initial
|
|
1212
|
+
})
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
);
|
|
1216
|
+
return createMarketChartData({
|
|
1217
|
+
marketId: outcomeId,
|
|
1218
|
+
interval: (_a2 = response.resolution) != null ? _a2 : interval,
|
|
1219
|
+
startTs,
|
|
1220
|
+
endTs,
|
|
1221
|
+
response
|
|
1222
|
+
});
|
|
1223
|
+
}));
|
|
652
1224
|
}),
|
|
653
1225
|
enabled: isQueryEnabled,
|
|
1226
|
+
meta: { chartWindow: rangeKey ? "rolling" : "fixed", chartEndTs: endTs },
|
|
654
1227
|
// Treat data as fresh for one bucket — within that window the
|
|
655
1228
|
// existing entry serves remounts without a refetch, and the
|
|
656
1229
|
// `refetchInterval` below schedules the next bucket's refresh.
|
|
657
|
-
staleTime:
|
|
1230
|
+
staleTime: (query) => {
|
|
1231
|
+
var _a2;
|
|
1232
|
+
if (rangeKey && endTs != null && ((_a2 = query.state.data) == null ? void 0 : _a2.endTs) != null && query.state.data.endTs < endTs)
|
|
1233
|
+
return 0;
|
|
1234
|
+
return staleTimeMs != null ? staleTimeMs : refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : 3e4;
|
|
1235
|
+
},
|
|
658
1236
|
// 60 min — survives typical tab/page revisits without re-fetching.
|
|
659
1237
|
gcTime: 60 * 6e4,
|
|
660
|
-
refetchOnWindowFocus: false
|
|
661
|
-
|
|
1238
|
+
refetchOnWindowFocus: false
|
|
1239
|
+
}, withReadRetry({
|
|
1240
|
+
retry: (failureCount, error) => {
|
|
1241
|
+
if (error instanceof ChartDeliveryError) {
|
|
1242
|
+
if (error.state === "unsupported") return false;
|
|
1243
|
+
if (error.state === "warming") return failureCount < 8;
|
|
1244
|
+
}
|
|
1245
|
+
return failureCount < 1;
|
|
1246
|
+
},
|
|
1247
|
+
retryDelay: (_attempt, error) => error instanceof ChartDeliveryError && error.retryAfterMs != null ? Math.min(error.state === "warming" ? 1e3 : 5e3, Math.max(0, error.retryAfterMs)) : 1e3
|
|
1248
|
+
})), {
|
|
662
1249
|
placeholderData: keepPreviousData2,
|
|
663
|
-
refetchInterval:
|
|
1250
|
+
refetchInterval: (query) => chartRefetchInterval(
|
|
1251
|
+
query,
|
|
1252
|
+
refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : false
|
|
1253
|
+
),
|
|
664
1254
|
refetchIntervalInBackground: false
|
|
665
1255
|
}))
|
|
666
1256
|
});
|
|
1257
|
+
const liveStates = useLiveStates(isQueryEnabled ? outcomeIds : []);
|
|
1258
|
+
const overlaid = queries.map((query, index) => {
|
|
1259
|
+
var _a2, _b2;
|
|
1260
|
+
return __spreadProps(__spreadValues({}, query), {
|
|
1261
|
+
data: ((_a2 = query.data) == null ? void 0 : _a2.marketId) === outcomeIds[index] ? overlayCandleTail(query.data, (_b2 = liveStates[index]) == null ? void 0 : _b2.data, !!rangeKey) : void 0
|
|
1262
|
+
});
|
|
1263
|
+
});
|
|
1264
|
+
const availability = {};
|
|
1265
|
+
if (isQueryEnabled)
|
|
1266
|
+
queries.forEach((query, index) => {
|
|
1267
|
+
var _a2, _b2, _c, _d;
|
|
1268
|
+
const sameOutcome = ((_a2 = query.data) == null ? void 0 : _a2.marketId) === outcomeIds[index];
|
|
1269
|
+
const metadata = sameOutcome ? (_b2 = query.data) == null ? void 0 : _b2.delivery : void 0;
|
|
1270
|
+
const error = query.error;
|
|
1271
|
+
const pending = query.isLoading || query.isPlaceholderData || query.isFetching;
|
|
1272
|
+
const state = error instanceof ChartDeliveryError ? error.state : error ? "failed" : pending || !sameOutcome ? "warming" : (_c = metadata == null ? void 0 : metadata.state) != null ? _c : Object.values(query.data.venues).some(
|
|
1273
|
+
(venue) => venue.candles.length > 0 || venue.liveCandle
|
|
1274
|
+
) ? "ready" : "empty";
|
|
1275
|
+
availability[outcomeIds[index]] = __spreadValues(__spreadProps(__spreadValues({}, metadata), {
|
|
1276
|
+
state,
|
|
1277
|
+
complete: (state === "ready" || state === "empty") && ((_d = metadata == null ? void 0 : metadata.complete) != null ? _d : true)
|
|
1278
|
+
}), error instanceof ChartDeliveryError && error.retryAfterMs != null ? { retryAfterMs: error.retryAfterMs } : {});
|
|
1279
|
+
});
|
|
1280
|
+
return {
|
|
1281
|
+
queries: overlaid,
|
|
1282
|
+
availability,
|
|
1283
|
+
outcomeIds,
|
|
1284
|
+
primaryOutcomeId,
|
|
1285
|
+
interval,
|
|
1286
|
+
startTs,
|
|
1287
|
+
endTs,
|
|
1288
|
+
isQueryEnabled,
|
|
1289
|
+
liveEnabled: liveEnabled && subscribedIds.length > 0,
|
|
1290
|
+
isConnected
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
function useMarketCharts(options) {
|
|
1294
|
+
const { queries, availability, outcomeIds, isQueryEnabled, liveEnabled, isConnected } = useMarketChartQueries(options);
|
|
1295
|
+
const charts = {};
|
|
1296
|
+
const errors = {};
|
|
1297
|
+
queries.forEach((query, index) => {
|
|
1298
|
+
var _a;
|
|
1299
|
+
const outcomeId = outcomeIds[index];
|
|
1300
|
+
if (((_a = query.data) == null ? void 0 : _a.marketId) === outcomeId && !query.isPlaceholderData)
|
|
1301
|
+
charts[outcomeId] = query.data;
|
|
1302
|
+
if (query.error)
|
|
1303
|
+
errors[outcomeId] = query.error instanceof Error ? query.error : new Error(String(query.error));
|
|
1304
|
+
});
|
|
1305
|
+
return {
|
|
1306
|
+
availability,
|
|
1307
|
+
charts,
|
|
1308
|
+
errors,
|
|
1309
|
+
isLoading: Boolean(
|
|
1310
|
+
isQueryEnabled && queries.some((query) => query.isLoading || query.isPlaceholderData)
|
|
1311
|
+
),
|
|
1312
|
+
isLive: Boolean(isQueryEnabled && liveEnabled && isConnected),
|
|
1313
|
+
refetch: () => __async(null, null, function* () {
|
|
1314
|
+
return Promise.all(queries.map((query) => query.refetch()));
|
|
1315
|
+
})
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function useMarketChart(options) {
|
|
1319
|
+
var _a, _b, _c, _d;
|
|
1320
|
+
const {
|
|
1321
|
+
queries,
|
|
1322
|
+
availability,
|
|
1323
|
+
primaryOutcomeId,
|
|
1324
|
+
interval,
|
|
1325
|
+
startTs,
|
|
1326
|
+
endTs,
|
|
1327
|
+
isQueryEnabled,
|
|
1328
|
+
liveEnabled,
|
|
1329
|
+
isConnected
|
|
1330
|
+
} = useMarketChartQueries(options);
|
|
667
1331
|
const successfulDatasets = queries.flatMap((query) => {
|
|
668
1332
|
return query.data ? [query.data] : [];
|
|
669
1333
|
});
|
|
670
1334
|
const data = primaryOutcomeId && successfulDatasets.length > 0 ? mergeMarketChartData({
|
|
671
1335
|
marketId: primaryOutcomeId,
|
|
672
|
-
interval,
|
|
1336
|
+
interval: (_b = (_a = successfulDatasets[0]) == null ? void 0 : _a.interval) != null ? _b : interval,
|
|
673
1337
|
startTs,
|
|
674
1338
|
endTs,
|
|
675
1339
|
datasets: successfulDatasets
|
|
676
1340
|
}) : null;
|
|
677
|
-
const hasPendingQuery = queries.some((query) => query.isLoading);
|
|
678
|
-
const firstError = (
|
|
1341
|
+
const hasPendingQuery = queries.some((query) => query.isLoading || query.isPlaceholderData);
|
|
1342
|
+
const firstError = (_d = (_c = queries.find((query) => query.error != null)) == null ? void 0 : _c.error) != null ? _d : null;
|
|
679
1343
|
const error = data == null && !hasPendingQuery ? firstError instanceof Error ? firstError : firstError ? new Error(String(firstError)) : null : null;
|
|
680
|
-
const
|
|
1344
|
+
const isInRange = (candle) => (startTs == null || candle.time >= startTs / 1e3) && (endTs == null || candle.time <= endTs / 1e3);
|
|
1345
|
+
const hasVisibleHistory = queries.some(
|
|
1346
|
+
(query) => !query.isPlaceholderData && query.data && Object.entries(query.data.venues).some(
|
|
1347
|
+
([venueName, venue]) => (!options.visibleVenue || venueName === options.visibleVenue) && (venue.candles.some(isInRange) || venue.liveCandle != null && isInRange(venue.liveCandle))
|
|
1348
|
+
)
|
|
1349
|
+
);
|
|
1350
|
+
const isLoading = Boolean(isQueryEnabled && hasPendingQuery && !hasVisibleHistory);
|
|
681
1351
|
return {
|
|
682
1352
|
data,
|
|
1353
|
+
availability,
|
|
683
1354
|
isLoading,
|
|
684
1355
|
error,
|
|
685
|
-
isLive: Boolean(liveEnabled && primaryOutcomeId && isConnected),
|
|
1356
|
+
isLive: Boolean(isQueryEnabled && liveEnabled && primaryOutcomeId && isConnected),
|
|
686
1357
|
refetch: () => __async(null, null, function* () {
|
|
687
1358
|
return Promise.all(queries.map((query) => query.refetch()));
|
|
688
1359
|
})
|
|
@@ -690,13 +1361,13 @@ function useMarketChart(options) {
|
|
|
690
1361
|
}
|
|
691
1362
|
|
|
692
1363
|
// src/use-live-market-stores.ts
|
|
693
|
-
import { useEffect as
|
|
1364
|
+
import { useEffect as useEffect5, useMemo as useMemo3, useReducer, useRef as useRef3 } from "react";
|
|
694
1365
|
function useLiveMarketStores(venueMarketIds) {
|
|
695
1366
|
const ws = useAggWebSocket();
|
|
696
1367
|
const [, forceRender] = useReducer((c) => c + 1, 0);
|
|
697
|
-
const subsRef =
|
|
698
|
-
const stableKey =
|
|
699
|
-
|
|
1368
|
+
const subsRef = useRef3(/* @__PURE__ */ new Map());
|
|
1369
|
+
const stableKey = useMemo3(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
|
|
1370
|
+
useEffect5(() => {
|
|
700
1371
|
if (!ws || venueMarketIds.length === 0) return;
|
|
701
1372
|
const current = subsRef.current;
|
|
702
1373
|
const desired = new Set(venueMarketIds);
|
|
@@ -733,7 +1404,7 @@ function candleToLive(c, source) {
|
|
|
733
1404
|
function useLiveCandles(options) {
|
|
734
1405
|
var _a;
|
|
735
1406
|
const { market, interval = "5m", mode = "venue", startTs, endTs } = options;
|
|
736
|
-
const venueMarketIds =
|
|
1407
|
+
const venueMarketIds = useMemo4(() => {
|
|
737
1408
|
if (!market) return [];
|
|
738
1409
|
if (mode === "venue") return [market.id];
|
|
739
1410
|
const ids = [market.id];
|
|
@@ -753,7 +1424,7 @@ function useLiveCandles(options) {
|
|
|
753
1424
|
endTs: endTs != null ? endTs : null,
|
|
754
1425
|
enabled: !!restMarketId && startTs != null && endTs != null
|
|
755
1426
|
});
|
|
756
|
-
const liveData =
|
|
1427
|
+
const liveData = useMemo4(() => {
|
|
757
1428
|
if (builders.length === 0) return { closed: [], forming: null };
|
|
758
1429
|
if (mode === "venue" || builders.length === 1) {
|
|
759
1430
|
return {
|
|
@@ -766,7 +1437,7 @@ function useLiveCandles(options) {
|
|
|
766
1437
|
forming: mergeCandles(builders.map((b) => b.getForming(interval)))
|
|
767
1438
|
};
|
|
768
1439
|
}, [builders, interval, mode]);
|
|
769
|
-
const candles =
|
|
1440
|
+
const candles = useMemo4(() => {
|
|
770
1441
|
const byTime = /* @__PURE__ */ new Map();
|
|
771
1442
|
if (chartData) {
|
|
772
1443
|
const venueEntries = Object.values(chartData.venues);
|
|
@@ -791,7 +1462,7 @@ function useLiveCandles(options) {
|
|
|
791
1462
|
merged.sort((a, b) => a.time - b.time);
|
|
792
1463
|
return merged;
|
|
793
1464
|
}, [chartData, liveData.closed]);
|
|
794
|
-
const liveCandle =
|
|
1465
|
+
const liveCandle = useMemo4(() => {
|
|
795
1466
|
if (!liveData.forming) return null;
|
|
796
1467
|
return candleToLive(liveData.forming, "live");
|
|
797
1468
|
}, [liveData.forming]);
|
|
@@ -850,8 +1521,8 @@ function useLiveCandleOverlay(options) {
|
|
|
850
1521
|
}),
|
|
851
1522
|
[scale]
|
|
852
1523
|
);
|
|
853
|
-
const scaledCandles =
|
|
854
|
-
const liveCandle =
|
|
1524
|
+
const scaledCandles = useMemo5(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
|
|
1525
|
+
const liveCandle = useMemo5(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
|
|
855
1526
|
return {
|
|
856
1527
|
liveCandle,
|
|
857
1528
|
scaledCandles,
|
|
@@ -862,7 +1533,7 @@ function useLiveCandleOverlay(options) {
|
|
|
862
1533
|
}
|
|
863
1534
|
|
|
864
1535
|
// src/use-event-orderbook-data.ts
|
|
865
|
-
import { useEffect as
|
|
1536
|
+
import { useEffect as useEffect6, useMemo as useMemo6 } from "react";
|
|
866
1537
|
function extractSelectedOutcomeIds(selectedMarket) {
|
|
867
1538
|
var _a, _b, _c;
|
|
868
1539
|
if (!selectedMarket) return [];
|
|
@@ -882,17 +1553,17 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
|
|
|
882
1553
|
const {
|
|
883
1554
|
features: { enableLiveUpdates }
|
|
884
1555
|
} = useAggUiConfig();
|
|
885
|
-
const selectedMarket =
|
|
1556
|
+
const selectedMarket = useMemo6(() => {
|
|
886
1557
|
var _a;
|
|
887
1558
|
if (!selectedMarketId || !(venueMarkets == null ? void 0 : venueMarkets.length)) return null;
|
|
888
1559
|
return (_a = venueMarkets.find((m) => m.id === selectedMarketId)) != null ? _a : null;
|
|
889
1560
|
}, [venueMarkets, selectedMarketId]);
|
|
890
|
-
const selectedOutcomeIds =
|
|
1561
|
+
const selectedOutcomeIds = useMemo6(
|
|
891
1562
|
() => extractSelectedOutcomeIds(selectedMarket),
|
|
892
1563
|
[selectedMarket]
|
|
893
1564
|
);
|
|
894
1565
|
const selectedKey = selectedOutcomeIds.join("|");
|
|
895
|
-
|
|
1566
|
+
useEffect6(() => {
|
|
896
1567
|
if (!ws || !enableLiveUpdates || !selectedOutcomeIds.length) return;
|
|
897
1568
|
const unsubscribers = selectedOutcomeIds.map((id) => ws.subscribe(id, "orderbook"));
|
|
898
1569
|
return () => {
|
|
@@ -901,8 +1572,11 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
|
|
|
901
1572
|
}, [ws, selectedKey, enableLiveUpdates]);
|
|
902
1573
|
}
|
|
903
1574
|
|
|
904
|
-
// src/use-
|
|
905
|
-
import { useQuery as
|
|
1575
|
+
// src/use-market-orderbook.ts
|
|
1576
|
+
import { useQuery as useQuery5, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
1577
|
+
|
|
1578
|
+
// src/market-data/orderbook-snapshot.ts
|
|
1579
|
+
var orderbookTimestampSeconds = (timestamp) => timestamp >= 1e12 ? timestamp / 1e3 : timestamp;
|
|
906
1580
|
function outcomeOrderbookToState(response, marketId) {
|
|
907
1581
|
var _a, _b, _c, _d;
|
|
908
1582
|
const { venue, orderbook, midpoint, spread, seq, checksum, timestamp, venueMarketOutcomeId } = response;
|
|
@@ -936,56 +1610,351 @@ function outcomeOrderbookToState(response, marketId) {
|
|
|
936
1610
|
spread,
|
|
937
1611
|
seq,
|
|
938
1612
|
checksum,
|
|
939
|
-
timestamp
|
|
1613
|
+
timestamp: orderbookTimestampSeconds(timestamp)
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// src/market-data/orderbook-cache.ts
|
|
1618
|
+
var truncateLevels = (levels, depth) => {
|
|
1619
|
+
if (depth == null) return levels;
|
|
1620
|
+
return levels.slice(0, Math.max(0, depth));
|
|
1621
|
+
};
|
|
1622
|
+
var truncateVenueOrderbooks = (venueOrderbooks, depth) => {
|
|
1623
|
+
if (depth == null) return venueOrderbooks;
|
|
1624
|
+
return Object.fromEntries(
|
|
1625
|
+
Object.entries(venueOrderbooks).map(([venue, book]) => [
|
|
1626
|
+
venue,
|
|
1627
|
+
{
|
|
1628
|
+
bids: truncateLevels(book.bids, depth),
|
|
1629
|
+
asks: truncateLevels(book.asks, depth)
|
|
1630
|
+
}
|
|
1631
|
+
])
|
|
1632
|
+
);
|
|
1633
|
+
};
|
|
1634
|
+
var aggregateVenueLevels = (venueOrderbooks, side) => {
|
|
1635
|
+
var _a;
|
|
1636
|
+
const levelsByPrice = /* @__PURE__ */ new Map();
|
|
1637
|
+
for (const [venue, orderbook] of Object.entries(venueOrderbooks)) {
|
|
1638
|
+
for (const level of orderbook[side]) {
|
|
1639
|
+
const currentLevel = levelsByPrice.get(level.price);
|
|
1640
|
+
if (currentLevel) {
|
|
1641
|
+
currentLevel.size += level.size;
|
|
1642
|
+
currentLevel.venues[venue] = ((_a = currentLevel.venues[venue]) != null ? _a : 0) + level.size;
|
|
1643
|
+
continue;
|
|
1644
|
+
}
|
|
1645
|
+
levelsByPrice.set(level.price, {
|
|
1646
|
+
price: level.price,
|
|
1647
|
+
size: level.size,
|
|
1648
|
+
venues: {
|
|
1649
|
+
[venue]: level.size
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
return [...levelsByPrice.values()].sort(
|
|
1655
|
+
(left, right) => side === "bids" ? right.price - left.price : left.price - right.price
|
|
1656
|
+
);
|
|
1657
|
+
};
|
|
1658
|
+
var createMarketOrderbookDataFromVenueOrderbooks = ({
|
|
1659
|
+
marketId,
|
|
1660
|
+
venueOrderbooks,
|
|
1661
|
+
timestamp = Math.floor(Date.now() / 1e3)
|
|
1662
|
+
}) => {
|
|
1663
|
+
var _a, _b, _c, _d;
|
|
1664
|
+
const bids = aggregateVenueLevels(venueOrderbooks, "bids");
|
|
1665
|
+
const asks = aggregateVenueLevels(venueOrderbooks, "asks");
|
|
1666
|
+
const bestBid = (_b = (_a = bids[0]) == null ? void 0 : _a.price) != null ? _b : null;
|
|
1667
|
+
const bestAsk = (_d = (_c = asks[0]) == null ? void 0 : _c.price) != null ? _d : null;
|
|
1668
|
+
return {
|
|
1669
|
+
marketId,
|
|
1670
|
+
orderbook: {
|
|
1671
|
+
bids,
|
|
1672
|
+
asks
|
|
1673
|
+
},
|
|
1674
|
+
venueOrderbooks,
|
|
1675
|
+
venues: Object.fromEntries(
|
|
1676
|
+
Object.entries(venueOrderbooks).map(([venue, orderbook]) => {
|
|
1677
|
+
var _a2, _b2, _c2, _d2;
|
|
1678
|
+
return [
|
|
1679
|
+
venue,
|
|
1680
|
+
{
|
|
1681
|
+
bestBid: (_b2 = (_a2 = orderbook.bids[0]) == null ? void 0 : _a2.price) != null ? _b2 : null,
|
|
1682
|
+
bestAsk: (_d2 = (_c2 = orderbook.asks[0]) == null ? void 0 : _c2.price) != null ? _d2 : null
|
|
1683
|
+
}
|
|
1684
|
+
];
|
|
1685
|
+
})
|
|
1686
|
+
),
|
|
1687
|
+
midpoint: bestBid != null && bestAsk != null ? (bestBid + bestAsk) / 2 : null,
|
|
1688
|
+
spread: bestBid != null && bestAsk != null ? bestAsk - bestBid : null,
|
|
1689
|
+
timestamp,
|
|
1690
|
+
snapshotVersion: 0,
|
|
1691
|
+
integrity: "ok"
|
|
1692
|
+
};
|
|
1693
|
+
};
|
|
1694
|
+
var createMarketOrderbookDataFromState = (state, options) => {
|
|
1695
|
+
var _a;
|
|
1696
|
+
return {
|
|
1697
|
+
marketId: state.marketId,
|
|
1698
|
+
orderbook: {
|
|
1699
|
+
bids: state.bids,
|
|
1700
|
+
asks: state.asks
|
|
1701
|
+
},
|
|
1702
|
+
venueOrderbooks: state.venueOrderbooks,
|
|
1703
|
+
venues: state.venues,
|
|
1704
|
+
midpoint: state.midpoint,
|
|
1705
|
+
spread: state.spread,
|
|
1706
|
+
timestamp: state.timestamp,
|
|
1707
|
+
snapshotVersion: (_a = options == null ? void 0 : options.snapshotVersion) != null ? _a : 0,
|
|
1708
|
+
seq: state.seq,
|
|
1709
|
+
checksum: state.checksum,
|
|
1710
|
+
integrity: "ok"
|
|
1711
|
+
};
|
|
1712
|
+
};
|
|
1713
|
+
var marketOrderbookDataToResponse = (data) => {
|
|
1714
|
+
return {
|
|
1715
|
+
venueMarketId: data.marketId,
|
|
1716
|
+
orderbook: data.orderbook,
|
|
1717
|
+
venueOrderbooks: data.venueOrderbooks,
|
|
1718
|
+
venues: data.venues,
|
|
1719
|
+
midpoint: data.midpoint,
|
|
1720
|
+
spread: data.spread,
|
|
1721
|
+
timestamp: data.timestamp,
|
|
1722
|
+
seq: data.seq,
|
|
1723
|
+
checksum: data.checksum,
|
|
1724
|
+
matchedMarkets: data.matchedMarkets
|
|
1725
|
+
};
|
|
1726
|
+
};
|
|
1727
|
+
var applyOrderbookDepth = (data, depth) => {
|
|
1728
|
+
if (depth == null) return data;
|
|
1729
|
+
return __spreadProps(__spreadValues({}, data), {
|
|
1730
|
+
orderbook: {
|
|
1731
|
+
bids: truncateLevels(data.orderbook.bids, depth),
|
|
1732
|
+
asks: truncateLevels(data.orderbook.asks, depth)
|
|
1733
|
+
},
|
|
1734
|
+
venueOrderbooks: truncateVenueOrderbooks(data.venueOrderbooks, depth)
|
|
1735
|
+
});
|
|
1736
|
+
};
|
|
1737
|
+
|
|
1738
|
+
// src/market-data/snapshot-selection.ts
|
|
1739
|
+
import { computeChecksum } from "@agg-build/sdk";
|
|
1740
|
+
var SOCKET_GRACE_MS = 200;
|
|
1741
|
+
var REST_BUDGET_MS = 1500;
|
|
1742
|
+
var MAX_SEED_AGE_MS = 5e3;
|
|
1743
|
+
function hasFreshSnapshot(store, id, now = Date.now()) {
|
|
1744
|
+
const state = store.get(id);
|
|
1745
|
+
return !!state.orderbook && state.integrity === "ok" && now - state.orderbook.timestamp * 1e3 <= MAX_SEED_AGE_MS && state.orderbook.timestamp * 1e3 <= now + 1e3;
|
|
1746
|
+
}
|
|
1747
|
+
function createOrderbookSnapshotQuery(client, store, ids, socketHealthy) {
|
|
1748
|
+
return fetchSnapshotQuery.bind(null, client, store, ids, socketHealthy);
|
|
1749
|
+
}
|
|
1750
|
+
function fetchSnapshotQuery(client, store, ids, socketHealthy, { signal }) {
|
|
1751
|
+
return selectOrderbookSnapshots(client, store, ids, socketHealthy, signal);
|
|
1752
|
+
}
|
|
1753
|
+
function selectOrderbookSnapshots(client, store, ids, socketHealthy, signal) {
|
|
1754
|
+
return __async(this, null, function* () {
|
|
1755
|
+
if (ids.length > 100) throw new Error("Orderbook snapshot batch exceeds 100 outcomes");
|
|
1756
|
+
const missing = () => ids.filter((id) => !hasFreshSnapshot(store, id));
|
|
1757
|
+
if (!missing().length || signal.aborted) return {};
|
|
1758
|
+
if (socketHealthy) {
|
|
1759
|
+
yield new Promise((resolve) => {
|
|
1760
|
+
let unsubscribe2 = () => {
|
|
1761
|
+
};
|
|
1762
|
+
const finish = () => {
|
|
1763
|
+
clearTimeout(timer2);
|
|
1764
|
+
unsubscribe2();
|
|
1765
|
+
signal.removeEventListener("abort", finish);
|
|
1766
|
+
resolve();
|
|
1767
|
+
};
|
|
1768
|
+
const timer2 = setTimeout(finish, SOCKET_GRACE_MS);
|
|
1769
|
+
unsubscribe2 = store.subscribe(ids, () => {
|
|
1770
|
+
if (!missing().length) finish();
|
|
1771
|
+
});
|
|
1772
|
+
signal.addEventListener("abort", finish, { once: true });
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
const requested = missing();
|
|
1776
|
+
if (!requested.length || signal.aborted) return {};
|
|
1777
|
+
const initialStates = new Map(requested.map((id) => [id, store.get(id)]));
|
|
1778
|
+
const controller = new AbortController();
|
|
1779
|
+
const abort = () => controller.abort();
|
|
1780
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
1781
|
+
const timer = setTimeout(abort, REST_BUDGET_MS);
|
|
1782
|
+
const unsubscribe = store.subscribe(requested, () => {
|
|
1783
|
+
if (!missing().length) controller.abort();
|
|
1784
|
+
});
|
|
1785
|
+
try {
|
|
1786
|
+
const response = yield client.getOutcomeOrderbooks(
|
|
1787
|
+
{ venueMarketOutcomeIds: requested },
|
|
1788
|
+
{ signal: controller.signal }
|
|
1789
|
+
);
|
|
1790
|
+
if (signal.aborted) return {};
|
|
1791
|
+
return Object.fromEntries(
|
|
1792
|
+
response.data.flatMap((book, index) => {
|
|
1793
|
+
const id = requested[index];
|
|
1794
|
+
if (!book || !id || hasFreshSnapshot(store, id)) return [];
|
|
1795
|
+
if (book.venueMarketOutcomeId !== id)
|
|
1796
|
+
throw new Error("Orderbook snapshot identity mismatch");
|
|
1797
|
+
if (!Number.isFinite(book.timestamp) || !Number.isSafeInteger(book.seq) || book.seq < 0 || !Number.isInteger(book.checksum))
|
|
1798
|
+
throw new Error("Invalid orderbook snapshot metadata");
|
|
1799
|
+
const snapshot = outcomeOrderbookToState(book, id);
|
|
1800
|
+
if (![...snapshot.bids, ...snapshot.asks].every(
|
|
1801
|
+
(level) => Number.isFinite(level.price) && Number.isFinite(level.size) && level.size >= 0
|
|
1802
|
+
))
|
|
1803
|
+
throw new Error("Invalid orderbook snapshot levels");
|
|
1804
|
+
const projectedChecksum = book.snapshotChecksum;
|
|
1805
|
+
if (projectedChecksum != null && computeChecksum(snapshot) !== projectedChecksum)
|
|
1806
|
+
throw new Error("Orderbook snapshot checksum mismatch");
|
|
1807
|
+
const current = store.get(id);
|
|
1808
|
+
const live = current.orderbook;
|
|
1809
|
+
const initial = initialStates.get(id);
|
|
1810
|
+
const initialBook = initial.orderbook;
|
|
1811
|
+
if (current.orderbookSnapshotVersion !== initial.orderbookSnapshotVersion || !!live !== !!initialBook || live && initialBook && (live.seq !== initialBook.seq || live.checksum !== initialBook.checksum || live.timestamp !== initialBook.timestamp))
|
|
1812
|
+
return [];
|
|
1813
|
+
if (live) {
|
|
1814
|
+
const sameGeneration = current.isConnected && current.integrity === "ok" && current.orderbookGeneration === current.connectionGeneration;
|
|
1815
|
+
if (snapshot.timestamp < live.timestamp || sameGeneration && snapshot.seq <= live.seq)
|
|
1816
|
+
return [];
|
|
1817
|
+
if (!sameGeneration && snapshot.timestamp <= live.timestamp) return [];
|
|
1818
|
+
}
|
|
1819
|
+
store.update(id, (previous) => __spreadProps(__spreadValues({}, previous), {
|
|
1820
|
+
orderbook: snapshot,
|
|
1821
|
+
integrity: "ok",
|
|
1822
|
+
orderbookError: null
|
|
1823
|
+
}));
|
|
1824
|
+
return [[id, book]];
|
|
1825
|
+
})
|
|
1826
|
+
);
|
|
1827
|
+
} catch (error) {
|
|
1828
|
+
if (signal.aborted || !missing().length) return {};
|
|
1829
|
+
throw error;
|
|
1830
|
+
} finally {
|
|
1831
|
+
clearTimeout(timer);
|
|
1832
|
+
unsubscribe();
|
|
1833
|
+
signal.removeEventListener("abort", abort);
|
|
1834
|
+
}
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
// src/use-market-orderbook.ts
|
|
1839
|
+
function useMarketOrderbook(options) {
|
|
1840
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1841
|
+
const queryClient = useQueryClient3();
|
|
1842
|
+
const client = useAggClient();
|
|
1843
|
+
const ws = useAggWebSocket();
|
|
1844
|
+
const isConnected = useAggWebSocketConnectionState();
|
|
1845
|
+
const {
|
|
1846
|
+
features: { enableLiveUpdates }
|
|
1847
|
+
} = useAggUiConfig();
|
|
1848
|
+
const { venueMarketOutcomeId, marketId, depth, enabled = true, venueOutcomes, live } = options;
|
|
1849
|
+
const selectedId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : marketId) != null ? _a : null;
|
|
1850
|
+
const liveEnabled = live != null ? live : enableLiveUpdates;
|
|
1851
|
+
const outcomeIds = venueOutcomes == null ? void 0 : venueOutcomes.map((v) => v.venueMarketOutcomeId).filter(Boolean);
|
|
1852
|
+
const subscriptionIds = (outcomeIds == null ? void 0 : outcomeIds.length) ? [...new Set(outcomeIds)] : selectedId ? [selectedId] : [];
|
|
1853
|
+
const selectedOutcomeId = (_b = subscriptionIds[0]) != null ? _b : null;
|
|
1854
|
+
useMarketDataSubscription({
|
|
1855
|
+
marketId: selectedOutcomeId,
|
|
1856
|
+
additionalMarketIds: subscriptionIds.slice(1),
|
|
1857
|
+
enabled: enabled && !!selectedOutcomeId,
|
|
1858
|
+
orderbook: true
|
|
1859
|
+
});
|
|
1860
|
+
const store = getMarketLiveStore(queryClient);
|
|
1861
|
+
const liveQueries = useLiveStates(enabled ? subscriptionIds : []);
|
|
1862
|
+
const sortedIds = [...subscriptionIds].sort();
|
|
1863
|
+
const preferSocket = enabled && Boolean(ws) && (isConnected || subscriptionIds.every((id) => {
|
|
1864
|
+
var _a2;
|
|
1865
|
+
return ((_a2 = store.get(id).connectionGeneration) != null ? _a2 : 0) === 0;
|
|
1866
|
+
}));
|
|
1867
|
+
const seedQuery = useQuery5({
|
|
1868
|
+
queryKey: ["market-orderbook-seed", sortedIds],
|
|
1869
|
+
queryFn: createOrderbookSnapshotQuery(client, store, sortedIds, preferSocket),
|
|
1870
|
+
enabled: enabled && subscriptionIds.length > 0,
|
|
1871
|
+
staleTime: 5e3,
|
|
1872
|
+
gcTime: 6e4,
|
|
1873
|
+
refetchOnWindowFocus: false,
|
|
1874
|
+
retry: false
|
|
1875
|
+
});
|
|
1876
|
+
const liveStates = subscriptionIds.map((subscriptionId, index) => {
|
|
1877
|
+
var _a2, _b2, _c2;
|
|
1878
|
+
return (_c2 = (_b2 = (_a2 = liveQueries[index]) == null ? void 0 : _a2.data) != null ? _b2 : store.peek(subscriptionId)) != null ? _c2 : createMarketLiveState(subscriptionId);
|
|
1879
|
+
});
|
|
1880
|
+
const seededOrderbooks = subscriptionIds.map((subscriptionId, index) => {
|
|
1881
|
+
var _a2, _b2, _c2, _d2;
|
|
1882
|
+
const liveBook = (_b2 = (_a2 = liveStates[index]) == null ? void 0 : _a2.orderbook) != null ? _b2 : null;
|
|
1883
|
+
if (liveBook) return liveBook;
|
|
1884
|
+
const seed = (_c2 = seedQuery.data) == null ? void 0 : _c2[subscriptionId];
|
|
1885
|
+
return ((_d2 = seed == null ? void 0 : seed.orderbook) == null ? void 0 : _d2.bids) && seed.orderbook.asks ? outcomeOrderbookToState(seed, subscriptionId) : null;
|
|
1886
|
+
});
|
|
1887
|
+
const primaryOrderbook = (_c = seededOrderbooks[0]) != null ? _c : null;
|
|
1888
|
+
const primarySnapshotVersion = (_e = (_d = liveStates[0]) == null ? void 0 : _d.orderbookSnapshotVersion) != null ? _e : 0;
|
|
1889
|
+
const data = primaryOrderbook ? applyOrderbookDepth(
|
|
1890
|
+
createMarketOrderbookDataFromState(primaryOrderbook, {
|
|
1891
|
+
snapshotVersion: primarySnapshotVersion
|
|
1892
|
+
}),
|
|
1893
|
+
depth
|
|
1894
|
+
) : null;
|
|
1895
|
+
const dataById = Object.fromEntries(
|
|
1896
|
+
seededOrderbooks.flatMap((orderbook, index) => {
|
|
1897
|
+
var _a2;
|
|
1898
|
+
if (!orderbook) return [];
|
|
1899
|
+
return [
|
|
1900
|
+
[
|
|
1901
|
+
subscriptionIds[index],
|
|
1902
|
+
applyOrderbookDepth(
|
|
1903
|
+
createMarketOrderbookDataFromState(orderbook, {
|
|
1904
|
+
snapshotVersion: (_a2 = liveStates[index]) == null ? void 0 : _a2.orderbookSnapshotVersion
|
|
1905
|
+
}),
|
|
1906
|
+
depth
|
|
1907
|
+
)
|
|
1908
|
+
]
|
|
1909
|
+
];
|
|
1910
|
+
})
|
|
1911
|
+
);
|
|
1912
|
+
const hasAnyOrderbook = seededOrderbooks.some((orderbook) => orderbook != null);
|
|
1913
|
+
const seedLoading = seedQuery.isLoading;
|
|
1914
|
+
const liveOrderbookErrorMessage = enabled && liveEnabled && !hasAnyOrderbook ? (_g = (_f = liveStates.find(
|
|
1915
|
+
(liveState) => typeof liveState.orderbookError === "string" && liveState.orderbookError.length > 0
|
|
1916
|
+
)) == null ? void 0 : _f.orderbookError) != null ? _g : null : null;
|
|
1917
|
+
return {
|
|
1918
|
+
data,
|
|
1919
|
+
dataById,
|
|
1920
|
+
isLoading: enabled && !hasAnyOrderbook && liveOrderbookErrorMessage == null && seedLoading,
|
|
1921
|
+
error: liveOrderbookErrorMessage ? new Error(liveOrderbookErrorMessage) : !hasAnyOrderbook && seedQuery.error instanceof Error ? seedQuery.error : null,
|
|
1922
|
+
isLive: Boolean(enabled && liveEnabled && selectedOutcomeId && isConnected),
|
|
1923
|
+
refetch: () => __async(null, null, function* () {
|
|
1924
|
+
if (!enabled) return;
|
|
1925
|
+
if (subscriptionIds.length === 0) return;
|
|
1926
|
+
subscriptionIds.forEach(
|
|
1927
|
+
(subscriptionId) => store.update(subscriptionId, (previous) => __spreadProps(__spreadValues({}, previous), { orderbookError: null }))
|
|
1928
|
+
);
|
|
1929
|
+
ws == null ? void 0 : ws.resnapshot(subscriptionIds);
|
|
1930
|
+
return seedQuery.refetch();
|
|
1931
|
+
})
|
|
940
1932
|
};
|
|
941
1933
|
}
|
|
1934
|
+
|
|
1935
|
+
// src/use-live-market.ts
|
|
942
1936
|
function useLiveMarket(canonicalMarketId) {
|
|
943
|
-
var _a, _b;
|
|
944
|
-
const client = useAggClient();
|
|
945
|
-
const isConnected = useAggWebSocketConnectionState();
|
|
946
1937
|
const {
|
|
947
1938
|
features: { enableLiveUpdates }
|
|
948
1939
|
} = useAggUiConfig();
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
const query = useQuery3({
|
|
956
|
-
queryKey: marketDataKeys.live(canonicalMarketId != null ? canonicalMarketId : "__disabled__"),
|
|
957
|
-
queryFn: () => __async(null, null, function* () {
|
|
958
|
-
return createMarketLiveState(canonicalMarketId != null ? canonicalMarketId : "__disabled__");
|
|
959
|
-
}),
|
|
960
|
-
enabled: false,
|
|
961
|
-
staleTime: Infinity,
|
|
962
|
-
gcTime: 5 * 6e4,
|
|
963
|
-
initialData: () => createMarketLiveState(canonicalMarketId != null ? canonicalMarketId : "__disabled__", {
|
|
964
|
-
isConnected: Boolean(isLiveSubscriptionEnabled && isConnected)
|
|
965
|
-
})
|
|
966
|
-
});
|
|
967
|
-
const seedQuery = useQuery3({
|
|
968
|
-
queryKey: ["live-market-seed", canonicalMarketId],
|
|
969
|
-
queryFn: ({ signal }) => canonicalMarketId ? client.getOutcomeOrderbook(canonicalMarketId, { signal }) : Promise.resolve(null),
|
|
970
|
-
enabled: Boolean(canonicalMarketId),
|
|
971
|
-
staleTime: 5e3,
|
|
972
|
-
gcTime: 6e4,
|
|
973
|
-
refetchOnWindowFocus: false,
|
|
974
|
-
retry: 1
|
|
1940
|
+
const connected = useAggWebSocketConnectionState();
|
|
1941
|
+
const [snapshot] = useLiveStates([canonicalMarketId != null ? canonicalMarketId : "__disabled__"]);
|
|
1942
|
+
useMarketOrderbook({
|
|
1943
|
+
venueMarketOutcomeId: canonicalMarketId,
|
|
1944
|
+
enabled: !!canonicalMarketId,
|
|
1945
|
+
live: enableLiveUpdates
|
|
975
1946
|
});
|
|
976
|
-
const data =
|
|
977
|
-
const orderbook = (_b = data.orderbook) != null ? _b : canonicalMarketId && seedQuery.data ? outcomeOrderbookToState(seedQuery.data, canonicalMarketId) : null;
|
|
1947
|
+
const data = snapshot.data;
|
|
978
1948
|
return {
|
|
979
|
-
orderbook,
|
|
1949
|
+
orderbook: data.orderbook,
|
|
980
1950
|
trades: data.trades,
|
|
981
|
-
isConnected:
|
|
1951
|
+
isConnected: !!canonicalMarketId && enableLiveUpdates && connected,
|
|
982
1952
|
integrity: data.integrity
|
|
983
1953
|
};
|
|
984
1954
|
}
|
|
985
1955
|
|
|
986
1956
|
// src/use-live-outcome-prices.ts
|
|
987
|
-
import { useMemo as
|
|
988
|
-
import { useQueries as useQueries3 } from "@tanstack/react-query";
|
|
1957
|
+
import { useMemo as useMemo7, useRef as useRef4 } from "react";
|
|
989
1958
|
var EMPTY_PRICES = /* @__PURE__ */ new Map();
|
|
990
1959
|
var buildMidpointFingerprint = (outcomeIds, queries) => {
|
|
991
1960
|
var _a, _b, _c;
|
|
@@ -1000,7 +1969,7 @@ function useLiveOutcomePrices(venueMarkets) {
|
|
|
1000
1969
|
const {
|
|
1001
1970
|
features: { enableLiveUpdates }
|
|
1002
1971
|
} = useAggUiConfig();
|
|
1003
|
-
const outcomeIds =
|
|
1972
|
+
const outcomeIds = useMemo7(() => {
|
|
1004
1973
|
var _a, _b;
|
|
1005
1974
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
|
|
1006
1975
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1014,22 +1983,13 @@ function useLiveOutcomePrices(venueMarkets) {
|
|
|
1014
1983
|
}
|
|
1015
1984
|
return [...ids].sort();
|
|
1016
1985
|
}, [venueMarkets]);
|
|
1017
|
-
const queries =
|
|
1018
|
-
queries: outcomeIds.map((id) => ({
|
|
1019
|
-
queryKey: marketDataKeys.live(id),
|
|
1020
|
-
queryFn: () => createMarketLiveState(id),
|
|
1021
|
-
enabled: false,
|
|
1022
|
-
staleTime: Infinity,
|
|
1023
|
-
gcTime: 5 * 6e4,
|
|
1024
|
-
initialData: () => createMarketLiveState(id)
|
|
1025
|
-
}))
|
|
1026
|
-
});
|
|
1986
|
+
const queries = useLiveStates(outcomeIds);
|
|
1027
1987
|
const fingerprint = buildMidpointFingerprint(outcomeIds, queries);
|
|
1028
|
-
const prevRef =
|
|
1988
|
+
const prevRef = useRef4({
|
|
1029
1989
|
fingerprint: "",
|
|
1030
1990
|
prices: EMPTY_PRICES
|
|
1031
1991
|
});
|
|
1032
|
-
const data =
|
|
1992
|
+
const data = useMemo7(() => {
|
|
1033
1993
|
var _a, _b, _c;
|
|
1034
1994
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return EMPTY_PRICES;
|
|
1035
1995
|
if (fingerprint === prevRef.current.fingerprint) {
|
|
@@ -1056,8 +2016,7 @@ function findLivePriceById(livePrices, id) {
|
|
|
1056
2016
|
}
|
|
1057
2017
|
|
|
1058
2018
|
// src/use-live-best-prices.ts
|
|
1059
|
-
import { useMemo as
|
|
1060
|
-
import { useQueries as useQueries4 } from "@tanstack/react-query";
|
|
2019
|
+
import { useMemo as useMemo8, useRef as useRef5 } from "react";
|
|
1061
2020
|
var EMPTY = /* @__PURE__ */ new Map();
|
|
1062
2021
|
var EMPTY_CANDIDATES = /* @__PURE__ */ new Map();
|
|
1063
2022
|
var extractOutcomeBestPrices = (state) => {
|
|
@@ -1086,7 +2045,7 @@ function useLiveBestPrices(venueMarkets) {
|
|
|
1086
2045
|
const {
|
|
1087
2046
|
features: { enableLiveUpdates }
|
|
1088
2047
|
} = useAggUiConfig();
|
|
1089
|
-
const outcomeIds =
|
|
2048
|
+
const outcomeIds = useMemo8(() => {
|
|
1090
2049
|
var _a, _b;
|
|
1091
2050
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
|
|
1092
2051
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1100,22 +2059,13 @@ function useLiveBestPrices(venueMarkets) {
|
|
|
1100
2059
|
}
|
|
1101
2060
|
return [...ids].sort();
|
|
1102
2061
|
}, [venueMarkets]);
|
|
1103
|
-
const queries =
|
|
1104
|
-
queries: outcomeIds.map((id) => ({
|
|
1105
|
-
queryKey: marketDataKeys.live(id),
|
|
1106
|
-
queryFn: () => createMarketLiveState(id),
|
|
1107
|
-
enabled: false,
|
|
1108
|
-
staleTime: Infinity,
|
|
1109
|
-
gcTime: 5 * 6e4,
|
|
1110
|
-
initialData: () => createMarketLiveState(id)
|
|
1111
|
-
}))
|
|
1112
|
-
});
|
|
2062
|
+
const queries = useLiveStates(outcomeIds);
|
|
1113
2063
|
const fingerprint = buildFingerprint(outcomeIds, queries);
|
|
1114
|
-
const prevRef =
|
|
2064
|
+
const prevRef = useRef5({
|
|
1115
2065
|
fingerprint: "",
|
|
1116
2066
|
result: EMPTY
|
|
1117
2067
|
});
|
|
1118
|
-
return
|
|
2068
|
+
return useMemo8(() => {
|
|
1119
2069
|
var _a, _b, _c, _d;
|
|
1120
2070
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length) || !enableLiveUpdates) return EMPTY;
|
|
1121
2071
|
if (fingerprint === prevRef.current.fingerprint) return prevRef.current.result;
|
|
@@ -1305,7 +2255,7 @@ function useLiveBestPriceCandidates(venueMarkets) {
|
|
|
1305
2255
|
const {
|
|
1306
2256
|
features: { enableLiveUpdates }
|
|
1307
2257
|
} = useAggUiConfig();
|
|
1308
|
-
const outcomeIds =
|
|
2258
|
+
const outcomeIds = useMemo8(() => {
|
|
1309
2259
|
var _a, _b;
|
|
1310
2260
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
|
|
1311
2261
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1319,22 +2269,13 @@ function useLiveBestPriceCandidates(venueMarkets) {
|
|
|
1319
2269
|
}
|
|
1320
2270
|
return [...ids].sort();
|
|
1321
2271
|
}, [venueMarkets]);
|
|
1322
|
-
const queries =
|
|
1323
|
-
queries: outcomeIds.map((id) => ({
|
|
1324
|
-
queryKey: marketDataKeys.live(id),
|
|
1325
|
-
queryFn: () => createMarketLiveState(id),
|
|
1326
|
-
enabled: false,
|
|
1327
|
-
staleTime: Infinity,
|
|
1328
|
-
gcTime: 5 * 6e4,
|
|
1329
|
-
initialData: () => createMarketLiveState(id)
|
|
1330
|
-
}))
|
|
1331
|
-
});
|
|
2272
|
+
const queries = useLiveStates(outcomeIds);
|
|
1332
2273
|
const fingerprint = buildCandidateFingerprint(outcomeIds, queries);
|
|
1333
|
-
const prevRef =
|
|
2274
|
+
const prevRef = useRef5({
|
|
1334
2275
|
fingerprint: "",
|
|
1335
2276
|
result: EMPTY_CANDIDATES
|
|
1336
2277
|
});
|
|
1337
|
-
return
|
|
2278
|
+
return useMemo8(() => {
|
|
1338
2279
|
if (!(venueMarkets == null ? void 0 : venueMarkets.length) || !enableLiveUpdates) return EMPTY_CANDIDATES;
|
|
1339
2280
|
if (fingerprint === prevRef.current.fingerprint) return prevRef.current.result;
|
|
1340
2281
|
const states = outcomeIds.map((_, i) => {
|
|
@@ -1363,8 +2304,8 @@ function useLiveTrades(canonicalMarketId) {
|
|
|
1363
2304
|
}
|
|
1364
2305
|
|
|
1365
2306
|
// src/use-midpoints.ts
|
|
1366
|
-
import { useQuery as
|
|
1367
|
-
import { useMemo as
|
|
2307
|
+
import { useQuery as useQuery6 } from "@tanstack/react-query";
|
|
2308
|
+
import { useMemo as useMemo9 } from "react";
|
|
1368
2309
|
var normalizeVenueMarketIds = (venueMarkets) => {
|
|
1369
2310
|
var _a;
|
|
1370
2311
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1376,6 +2317,21 @@ var normalizeVenueMarketIds = (venueMarkets) => {
|
|
|
1376
2317
|
}
|
|
1377
2318
|
return [...ids].sort((left, right) => left.localeCompare(right));
|
|
1378
2319
|
};
|
|
2320
|
+
var EMPTY_MIDPOINTS_POLL_MS = 5e3;
|
|
2321
|
+
var EMPTY_MIDPOINTS_MAX_FETCHES = 12;
|
|
2322
|
+
var hasUsableMidpoint = (item) => {
|
|
2323
|
+
var _a;
|
|
2324
|
+
if (!item) return false;
|
|
2325
|
+
if (item.midpoint != null) return true;
|
|
2326
|
+
return ((_a = item.outcomes) != null ? _a : []).some(
|
|
2327
|
+
(outcome) => outcome.midpoint != null || outcome.bestBid != null || outcome.bestAsk != null
|
|
2328
|
+
);
|
|
2329
|
+
};
|
|
2330
|
+
var isMidpointResponseComplete = (data, primaryVenueMarketIds) => {
|
|
2331
|
+
if (!(data == null ? void 0 : data.data)) return false;
|
|
2332
|
+
const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
|
|
2333
|
+
return primaryVenueMarketIds.every((id) => hasUsableMidpoint(itemByMarketId.get(id)));
|
|
2334
|
+
};
|
|
1379
2335
|
var normalizeOutcomeLabel = (label) => {
|
|
1380
2336
|
return typeof label === "string" ? label.trim().toLowerCase() : "";
|
|
1381
2337
|
};
|
|
@@ -1537,22 +2493,30 @@ function useMidpoints(venueMarkets, options) {
|
|
|
1537
2493
|
market: { maxMidpointIdsPerRequest: configuredMaxMidpointIdsPerRequest }
|
|
1538
2494
|
} = useAggUiConfig();
|
|
1539
2495
|
const maxMidpointIdsPerRequest = (_a = options == null ? void 0 : options.maxMidpointIdsPerRequest) != null ? _a : configuredMaxMidpointIdsPerRequest;
|
|
1540
|
-
const ids =
|
|
1541
|
-
const bestMidpointCandidateOutcomeIds =
|
|
2496
|
+
const ids = useMemo9(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
|
|
2497
|
+
const bestMidpointCandidateOutcomeIds = useMemo9(
|
|
1542
2498
|
() => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
|
|
1543
2499
|
[venueMarkets]
|
|
1544
2500
|
);
|
|
1545
|
-
const
|
|
2501
|
+
const primaryVenueMarketIds = useMemo9(
|
|
2502
|
+
() => (venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean),
|
|
2503
|
+
[venueMarkets]
|
|
2504
|
+
);
|
|
2505
|
+
const { data, isLoading } = useQuery6({
|
|
1546
2506
|
queryKey: ["midpoints", ids, maxMidpointIdsPerRequest],
|
|
1547
2507
|
queryFn: () => client.getMidpoints(ids, { bestPrice: true, maxMidpointIdsPerRequest }),
|
|
1548
2508
|
enabled: ids.length > 0,
|
|
1549
|
-
|
|
2509
|
+
// Complete responses stay cached for the session (unchanged behavior).
|
|
2510
|
+
// Incomplete ones are stale, so a remount refetches them and a short,
|
|
2511
|
+
// bounded poll picks up prices once a cold venue book warms.
|
|
2512
|
+
staleTime: (query) => isMidpointResponseComplete(query.state.data, primaryVenueMarketIds) ? Infinity : 0,
|
|
2513
|
+
refetchInterval: (query) => !isMidpointResponseComplete(query.state.data, primaryVenueMarketIds) && query.state.dataUpdateCount < EMPTY_MIDPOINTS_MAX_FETCHES ? EMPTY_MIDPOINTS_POLL_MS : false,
|
|
1550
2514
|
gcTime: 30 * 6e4,
|
|
1551
|
-
refetchOnMount:
|
|
2515
|
+
refetchOnMount: true,
|
|
1552
2516
|
refetchOnWindowFocus: false,
|
|
1553
2517
|
refetchOnReconnect: false
|
|
1554
2518
|
});
|
|
1555
|
-
const result =
|
|
2519
|
+
const result = useMemo9(() => {
|
|
1556
2520
|
var _a2, _b, _c, _d, _e, _f;
|
|
1557
2521
|
const map = /* @__PURE__ */ new Map();
|
|
1558
2522
|
const currentMap = /* @__PURE__ */ new Map();
|
|
@@ -1605,7 +2569,7 @@ function useMidpoints(venueMarkets, options) {
|
|
|
1605
2569
|
}
|
|
1606
2570
|
return { map, currentMap, venueMap };
|
|
1607
2571
|
}, [data, venueMarkets]);
|
|
1608
|
-
const { bestMidpoint, bestMidpointVenue } =
|
|
2572
|
+
const { bestMidpoint, bestMidpointVenue } = useMemo9(() => {
|
|
1609
2573
|
let value;
|
|
1610
2574
|
let venue;
|
|
1611
2575
|
for (const outcomeId of bestMidpointCandidateOutcomeIds) {
|
|
@@ -1626,7 +2590,7 @@ function useMidpoints(venueMarkets, options) {
|
|
|
1626
2590
|
}
|
|
1627
2591
|
return { bestMidpoint: value, bestMidpointVenue: venue };
|
|
1628
2592
|
}, [bestMidpointCandidateOutcomeIds, result.map, result.venueMap]);
|
|
1629
|
-
const { bestPrices, bestPriceVenuesByOutcomeId } =
|
|
2593
|
+
const { bestPrices, bestPriceVenuesByOutcomeId } = useMemo9(
|
|
1630
2594
|
() => extractBestPrices(data == null ? void 0 : data.data, venueMarkets),
|
|
1631
2595
|
[data == null ? void 0 : data.data, venueMarkets]
|
|
1632
2596
|
);
|
|
@@ -1644,7 +2608,7 @@ function useMidpoints(venueMarkets, options) {
|
|
|
1644
2608
|
}
|
|
1645
2609
|
|
|
1646
2610
|
// src/use-rolling-chart-window.ts
|
|
1647
|
-
import { useEffect as
|
|
2611
|
+
import { useEffect as useEffect7, useMemo as useMemo10, useState as useState4 } from "react";
|
|
1648
2612
|
var RANGE_SECONDS_BY_RANGE = {
|
|
1649
2613
|
"1H": 60 * 60,
|
|
1650
2614
|
"6H": 6 * 60 * 60,
|
|
@@ -1675,135 +2639,27 @@ var useRollingChartWindow = (options) => {
|
|
|
1675
2639
|
var _a;
|
|
1676
2640
|
const tickMs = (_a = options.tickMs) != null ? _a : 1e3;
|
|
1677
2641
|
const optionsNowMs = options.nowMs;
|
|
1678
|
-
const nowMs =
|
|
2642
|
+
const nowMs = useMemo10(() => optionsNowMs != null ? optionsNowMs : (() => Date.now()), [optionsNowMs]);
|
|
1679
2643
|
const [nowSec, setNowSec] = useState4(() => Math.floor(nowMs() / 1e3));
|
|
1680
|
-
|
|
2644
|
+
useEffect7(() => {
|
|
1681
2645
|
setNowSec(Math.floor(nowMs() / 1e3));
|
|
1682
2646
|
const handle = setInterval(() => {
|
|
1683
2647
|
setNowSec(Math.floor(nowMs() / 1e3));
|
|
1684
2648
|
}, tickMs);
|
|
1685
2649
|
return () => clearInterval(handle);
|
|
1686
2650
|
}, [tickMs, nowMs]);
|
|
1687
|
-
return
|
|
2651
|
+
return useMemo10(
|
|
1688
2652
|
() => resolveRollingWindow({ range: options.range, nowSec, interval: options.interval }),
|
|
1689
2653
|
[options.range, options.interval, nowSec]
|
|
1690
2654
|
);
|
|
1691
2655
|
};
|
|
1692
2656
|
|
|
1693
|
-
// src/use-market-orderbook.ts
|
|
1694
|
-
import { useQueries as useQueries5, useQueryClient } from "@tanstack/react-query";
|
|
1695
|
-
function useMarketOrderbook(options) {
|
|
1696
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1697
|
-
const queryClient = useQueryClient();
|
|
1698
|
-
const client = useAggClient();
|
|
1699
|
-
const ws = useAggWebSocket();
|
|
1700
|
-
const isConnected = useAggWebSocketConnectionState();
|
|
1701
|
-
const {
|
|
1702
|
-
features: { enableLiveUpdates }
|
|
1703
|
-
} = useAggUiConfig();
|
|
1704
|
-
const { venueMarketOutcomeId, marketId, depth, enabled = true, venueOutcomes, live } = options;
|
|
1705
|
-
const selectedId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : marketId) != null ? _a : null;
|
|
1706
|
-
const liveEnabled = live != null ? live : enableLiveUpdates;
|
|
1707
|
-
const outcomeIds = venueOutcomes == null ? void 0 : venueOutcomes.map((v) => v.venueMarketOutcomeId).filter(Boolean);
|
|
1708
|
-
const subscriptionIds = (outcomeIds == null ? void 0 : outcomeIds.length) ? [...new Set(outcomeIds)] : selectedId ? [selectedId] : [];
|
|
1709
|
-
const selectedOutcomeId = (_b = subscriptionIds[0]) != null ? _b : null;
|
|
1710
|
-
useMarketDataSubscription({
|
|
1711
|
-
marketId: selectedOutcomeId,
|
|
1712
|
-
additionalMarketIds: subscriptionIds.slice(1),
|
|
1713
|
-
enabled: enabled && !!selectedOutcomeId,
|
|
1714
|
-
orderbook: true
|
|
1715
|
-
});
|
|
1716
|
-
const liveQueries = useQueries5({
|
|
1717
|
-
queries: subscriptionIds.map((subscriptionId) => ({
|
|
1718
|
-
queryKey: marketDataKeys.live(subscriptionId),
|
|
1719
|
-
queryFn: () => createMarketLiveState(subscriptionId),
|
|
1720
|
-
staleTime: Infinity,
|
|
1721
|
-
gcTime: 5 * 6e4,
|
|
1722
|
-
refetchOnMount: false,
|
|
1723
|
-
refetchOnWindowFocus: false,
|
|
1724
|
-
refetchOnReconnect: false
|
|
1725
|
-
}))
|
|
1726
|
-
});
|
|
1727
|
-
const seedQueries = useQueries5({
|
|
1728
|
-
queries: subscriptionIds.map((subscriptionId) => ({
|
|
1729
|
-
queryKey: ["market-orderbook-seed", subscriptionId],
|
|
1730
|
-
queryFn: ({ signal }) => client.getOutcomeOrderbook(subscriptionId, { signal }),
|
|
1731
|
-
enabled: enabled && !!subscriptionId,
|
|
1732
|
-
staleTime: 5e3,
|
|
1733
|
-
gcTime: 6e4,
|
|
1734
|
-
refetchOnWindowFocus: false,
|
|
1735
|
-
retry: 1
|
|
1736
|
-
}))
|
|
1737
|
-
});
|
|
1738
|
-
const liveStates = subscriptionIds.map((subscriptionId, index) => {
|
|
1739
|
-
var _a2, _b2;
|
|
1740
|
-
return (_b2 = (_a2 = liveQueries[index]) == null ? void 0 : _a2.data) != null ? _b2 : createMarketLiveState(subscriptionId);
|
|
1741
|
-
});
|
|
1742
|
-
const seededOrderbooks = subscriptionIds.map((subscriptionId, index) => {
|
|
1743
|
-
var _a2, _b2, _c2, _d2;
|
|
1744
|
-
const liveBook = (_b2 = (_a2 = liveStates[index]) == null ? void 0 : _a2.orderbook) != null ? _b2 : null;
|
|
1745
|
-
if (liveBook) return liveBook;
|
|
1746
|
-
const seed = (_c2 = seedQueries[index]) == null ? void 0 : _c2.data;
|
|
1747
|
-
return ((_d2 = seed == null ? void 0 : seed.orderbook) == null ? void 0 : _d2.bids) && seed.orderbook.asks ? outcomeOrderbookToState(seed, subscriptionId) : null;
|
|
1748
|
-
});
|
|
1749
|
-
const primaryOrderbook = (_c = seededOrderbooks[0]) != null ? _c : null;
|
|
1750
|
-
const primarySnapshotVersion = (_e = (_d = liveStates[0]) == null ? void 0 : _d.orderbookSnapshotVersion) != null ? _e : 0;
|
|
1751
|
-
const data = primaryOrderbook ? applyOrderbookDepth(
|
|
1752
|
-
createMarketOrderbookDataFromState(primaryOrderbook, {
|
|
1753
|
-
snapshotVersion: primarySnapshotVersion
|
|
1754
|
-
}),
|
|
1755
|
-
depth
|
|
1756
|
-
) : null;
|
|
1757
|
-
const dataById = Object.fromEntries(
|
|
1758
|
-
seededOrderbooks.flatMap((orderbook, index) => {
|
|
1759
|
-
var _a2;
|
|
1760
|
-
if (!orderbook) return [];
|
|
1761
|
-
return [
|
|
1762
|
-
[
|
|
1763
|
-
subscriptionIds[index],
|
|
1764
|
-
applyOrderbookDepth(
|
|
1765
|
-
createMarketOrderbookDataFromState(orderbook, {
|
|
1766
|
-
snapshotVersion: (_a2 = liveStates[index]) == null ? void 0 : _a2.orderbookSnapshotVersion
|
|
1767
|
-
}),
|
|
1768
|
-
depth
|
|
1769
|
-
)
|
|
1770
|
-
]
|
|
1771
|
-
];
|
|
1772
|
-
})
|
|
1773
|
-
);
|
|
1774
|
-
const hasAnyOrderbook = seededOrderbooks.some((orderbook) => orderbook != null);
|
|
1775
|
-
const seedLoading = seedQueries.some((query) => query.isLoading);
|
|
1776
|
-
const liveOrderbookErrorMessage = enabled && liveEnabled && !hasAnyOrderbook ? (_g = (_f = liveStates.find(
|
|
1777
|
-
(liveState) => typeof liveState.orderbookError === "string" && liveState.orderbookError.length > 0
|
|
1778
|
-
)) == null ? void 0 : _f.orderbookError) != null ? _g : null : null;
|
|
1779
|
-
return {
|
|
1780
|
-
data,
|
|
1781
|
-
dataById,
|
|
1782
|
-
isLoading: enabled && !hasAnyOrderbook && liveOrderbookErrorMessage == null && (isConnected || seedLoading),
|
|
1783
|
-
error: liveOrderbookErrorMessage ? new Error(liveOrderbookErrorMessage) : null,
|
|
1784
|
-
isLive: Boolean(liveEnabled && selectedOutcomeId && isConnected),
|
|
1785
|
-
refetch: () => __async(null, null, function* () {
|
|
1786
|
-
if (!enabled) return;
|
|
1787
|
-
if (subscriptionIds.length === 0) return;
|
|
1788
|
-
subscriptionIds.forEach((subscriptionId) => {
|
|
1789
|
-
queryClient.setQueryData(
|
|
1790
|
-
marketDataKeys.live(subscriptionId),
|
|
1791
|
-
(previous) => __spreadProps(__spreadValues({}, previous != null ? previous : createMarketLiveState(subscriptionId)), {
|
|
1792
|
-
orderbookError: null
|
|
1793
|
-
})
|
|
1794
|
-
);
|
|
1795
|
-
});
|
|
1796
|
-
ws == null ? void 0 : ws.resnapshot(subscriptionIds);
|
|
1797
|
-
})
|
|
1798
|
-
};
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
2657
|
// src/use-arb.ts
|
|
1802
|
-
import { useEffect as
|
|
2658
|
+
import { useEffect as useEffect8, useRef as useRef6, useState as useState5 } from "react";
|
|
1803
2659
|
function useMarketArb(marketId) {
|
|
1804
2660
|
const ws = useAggWebSocket();
|
|
1805
2661
|
const [state, setState] = useState5({ arbReturn: null, isLive: false });
|
|
1806
|
-
|
|
2662
|
+
useEffect8(() => {
|
|
1807
2663
|
if (!ws || !marketId) return;
|
|
1808
2664
|
const cached = ws.getArb(marketId);
|
|
1809
2665
|
if (cached != null) {
|
|
@@ -1823,9 +2679,9 @@ var EMPTY_ARB_FEED = {
|
|
|
1823
2679
|
function useArbFeed() {
|
|
1824
2680
|
const ws = useAggWebSocket();
|
|
1825
2681
|
const [state, setState] = useState5(EMPTY_ARB_FEED);
|
|
1826
|
-
const stateRef =
|
|
2682
|
+
const stateRef = useRef6(state);
|
|
1827
2683
|
stateRef.current = state;
|
|
1828
|
-
|
|
2684
|
+
useEffect8(() => {
|
|
1829
2685
|
if (!ws) return;
|
|
1830
2686
|
const off = ws.subscribeArbFeed((batch) => {
|
|
1831
2687
|
setState((prev) => {
|
|
@@ -1857,7 +2713,9 @@ function useArbFeed() {
|
|
|
1857
2713
|
}
|
|
1858
2714
|
|
|
1859
2715
|
// src/use-order-book.ts
|
|
1860
|
-
import { keepPreviousData as keepPreviousData3, useQuery as
|
|
2716
|
+
import { keepPreviousData as keepPreviousData3, useQuery as useQuery7 } from "@tanstack/react-query";
|
|
2717
|
+
var fetchBatchBookQuery = (client, venueMarketIds, { signal }) => client.getOrderbooks({ venueMarketIds }, { signal });
|
|
2718
|
+
var createBatchBookQuery = (client, venueMarketIds) => fetchBatchBookQuery.bind(null, client, venueMarketIds);
|
|
1861
2719
|
function useOrderBook(options) {
|
|
1862
2720
|
const client = useAggClient();
|
|
1863
2721
|
const { orderbooks, enabled = true, canonicalMarketId } = options;
|
|
@@ -1870,14 +2728,9 @@ function useOrderBook(options) {
|
|
|
1870
2728
|
venueMarketOutcomeId: outcome.id
|
|
1871
2729
|
})) : void 0
|
|
1872
2730
|
});
|
|
1873
|
-
const batchedResult =
|
|
2731
|
+
const batchedResult = useQuery7({
|
|
1874
2732
|
queryKey: requestedVenueMarketIds.length ? ["orderbooks", requestedVenueMarketIds, null] : ["orderbooks", "__disabled__", null],
|
|
1875
|
-
queryFn: (
|
|
1876
|
-
{
|
|
1877
|
-
venueMarketIds: requestedVenueMarketIds
|
|
1878
|
-
},
|
|
1879
|
-
{ signal }
|
|
1880
|
-
),
|
|
2733
|
+
queryFn: createBatchBookQuery(client, requestedVenueMarketIds),
|
|
1881
2734
|
enabled: enabled && !canonicalMarketId && requestedVenueMarketIds.length > 0,
|
|
1882
2735
|
staleTime: 1e4,
|
|
1883
2736
|
gcTime: 5 * 6e4,
|
|
@@ -1938,7 +2791,7 @@ function useOrderBook(options) {
|
|
|
1938
2791
|
}
|
|
1939
2792
|
|
|
1940
2793
|
// src/use-orderbook-quote.ts
|
|
1941
|
-
import { keepPreviousData as keepPreviousData4, useQuery as
|
|
2794
|
+
import { keepPreviousData as keepPreviousData4, useQuery as useQuery8 } from "@tanstack/react-query";
|
|
1942
2795
|
var QUOTE_DEBOUNCE_MS = 300;
|
|
1943
2796
|
var createUnavailableOrderbookError = (message, code, retryable) => {
|
|
1944
2797
|
const error = new Error(message);
|
|
@@ -2000,7 +2853,7 @@ function useOrderbookQuote(options) {
|
|
|
2000
2853
|
const { marketId, side, size, enabled = true } = options;
|
|
2001
2854
|
const debouncedSize = useDebouncedValue(size, QUOTE_DEBOUNCE_MS);
|
|
2002
2855
|
const shouldFetch = enabled && !!marketId && debouncedSize > 0;
|
|
2003
|
-
const query =
|
|
2856
|
+
const query = useQuery8({
|
|
2004
2857
|
queryKey: marketId ? marketDataKeys.orderbookQuote(marketId, side, debouncedSize) : ["market-data", "orderbook-quote", "__disabled__"],
|
|
2005
2858
|
queryFn: () => __async(null, null, function* () {
|
|
2006
2859
|
var _a2, _b, _c, _d;
|
|
@@ -2042,12 +2895,12 @@ function useOrderbookQuote(options) {
|
|
|
2042
2895
|
}
|
|
2043
2896
|
|
|
2044
2897
|
// src/use-orders.ts
|
|
2045
|
-
import { useQuery as
|
|
2898
|
+
import { useQuery as useQuery9 } from "@tanstack/react-query";
|
|
2046
2899
|
function useOrders(options = {}) {
|
|
2047
2900
|
var _a, _b, _c, _d;
|
|
2048
2901
|
const client = useAggClient();
|
|
2049
2902
|
const { userId, status, limit = 50, offset = 0, enabled = true } = options;
|
|
2050
|
-
const query =
|
|
2903
|
+
const query = useQuery9({
|
|
2051
2904
|
queryKey: ["orders", userId != null ? userId : "me", status != null ? status : "all", limit, offset],
|
|
2052
2905
|
queryFn: () => client.getOrders({
|
|
2053
2906
|
userId,
|
|
@@ -2070,15 +2923,24 @@ import {
|
|
|
2070
2923
|
keepPreviousData as keepPreviousData5,
|
|
2071
2924
|
useInfiniteQuery as useInfiniteQuery5
|
|
2072
2925
|
} from "@tanstack/react-query";
|
|
2073
|
-
import { useContext as useContext2, useEffect as
|
|
2926
|
+
import { useContext as useContext2, useEffect as useEffect9, useState as useState6 } from "react";
|
|
2074
2927
|
function useSearch(options) {
|
|
2075
2928
|
var _a, _b, _c, _d;
|
|
2076
2929
|
const client = useContext2(AggClientContext);
|
|
2077
2930
|
const queryClient = useContext2(QueryClientContext);
|
|
2078
2931
|
const [fallbackQueryClient] = useState6(() => new QueryClient());
|
|
2079
|
-
const {
|
|
2932
|
+
const {
|
|
2933
|
+
q,
|
|
2934
|
+
type,
|
|
2935
|
+
categoryIds,
|
|
2936
|
+
status,
|
|
2937
|
+
limit = 20,
|
|
2938
|
+
enabled = true,
|
|
2939
|
+
deep = false,
|
|
2940
|
+
mode = "full"
|
|
2941
|
+
} = options;
|
|
2080
2942
|
const isEnabled = enabled && q.length > 0;
|
|
2081
|
-
|
|
2943
|
+
useEffect9(() => {
|
|
2082
2944
|
if (queryClient) return void 0;
|
|
2083
2945
|
fallbackQueryClient.mount();
|
|
2084
2946
|
return () => {
|
|
@@ -2088,32 +2950,40 @@ function useSearch(options) {
|
|
|
2088
2950
|
if (isEnabled && !client) {
|
|
2089
2951
|
throw new Error("useSearch must be used within an <AggProvider>");
|
|
2090
2952
|
}
|
|
2953
|
+
const queryKey = [
|
|
2954
|
+
"search",
|
|
2955
|
+
q,
|
|
2956
|
+
type,
|
|
2957
|
+
(_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "",
|
|
2958
|
+
(_b = status == null ? void 0 : status.join(",")) != null ? _b : "",
|
|
2959
|
+
limit,
|
|
2960
|
+
deep,
|
|
2961
|
+
mode
|
|
2962
|
+
];
|
|
2963
|
+
const effectiveQueryClient = queryClient != null ? queryClient : fallbackQueryClient;
|
|
2964
|
+
const retryOptions = withReadRetry(effectiveQueryClient.defaultQueryOptions({ queryKey }));
|
|
2091
2965
|
const query = useInfiniteQuery5(
|
|
2092
|
-
{
|
|
2966
|
+
__spreadProps(__spreadValues({
|
|
2093
2967
|
// deep is part of the key — TanStack treats deep vs light as
|
|
2094
2968
|
// independent queries so users can have both modes cached side-by-side.
|
|
2095
|
-
queryKey
|
|
2096
|
-
|
|
2097
|
-
q,
|
|
2098
|
-
type,
|
|
2099
|
-
(_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "",
|
|
2100
|
-
(_b = status == null ? void 0 : status.join(",")) != null ? _b : "",
|
|
2101
|
-
limit,
|
|
2102
|
-
deep
|
|
2103
|
-
],
|
|
2104
|
-
queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
|
|
2969
|
+
queryKey,
|
|
2970
|
+
queryFn: (_0) => __async(null, [_0], function* ({ pageParam, signal }) {
|
|
2105
2971
|
if (!client) {
|
|
2106
2972
|
throw new Error("useSearch must be used within an <AggProvider>");
|
|
2107
2973
|
}
|
|
2108
|
-
const res = yield client.search(
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2974
|
+
const res = yield client.search(
|
|
2975
|
+
{
|
|
2976
|
+
q,
|
|
2977
|
+
type,
|
|
2978
|
+
categoryIds,
|
|
2979
|
+
status,
|
|
2980
|
+
limit,
|
|
2981
|
+
cursor: pageParam,
|
|
2982
|
+
deep,
|
|
2983
|
+
mode
|
|
2984
|
+
},
|
|
2985
|
+
{ signal }
|
|
2986
|
+
);
|
|
2117
2987
|
return res;
|
|
2118
2988
|
}),
|
|
2119
2989
|
initialPageParam: void 0,
|
|
@@ -2122,10 +2992,11 @@ function useSearch(options) {
|
|
|
2122
2992
|
if (!lastPage.hasMore) return void 0;
|
|
2123
2993
|
return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
|
|
2124
2994
|
},
|
|
2125
|
-
placeholderData: keepPreviousData5
|
|
2995
|
+
placeholderData: keepPreviousData5
|
|
2996
|
+
}, retryOptions), {
|
|
2126
2997
|
enabled: isEnabled && !!client
|
|
2127
|
-
},
|
|
2128
|
-
|
|
2998
|
+
}),
|
|
2999
|
+
effectiveQueryClient
|
|
2129
3000
|
);
|
|
2130
3001
|
const data = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((page) => page.data)) != null ? _d : [];
|
|
2131
3002
|
return {
|
|
@@ -2165,7 +3036,8 @@ function useMarketSearch(options) {
|
|
|
2165
3036
|
status,
|
|
2166
3037
|
limit,
|
|
2167
3038
|
enabled: suggestionsEnabled,
|
|
2168
|
-
deep: false
|
|
3039
|
+
deep: false,
|
|
3040
|
+
mode: "instant"
|
|
2169
3041
|
});
|
|
2170
3042
|
const submittedQ = (_a = submittedQuery == null ? void 0 : submittedQuery.trim()) != null ? _a : "";
|
|
2171
3043
|
const resultsQuery = useSearch({
|
|
@@ -2230,7 +3102,7 @@ function useMarketSearch(options) {
|
|
|
2230
3102
|
}
|
|
2231
3103
|
|
|
2232
3104
|
// src/use-smart-route.ts
|
|
2233
|
-
import { keepPreviousData as keepPreviousData6, useQuery as
|
|
3105
|
+
import { keepPreviousData as keepPreviousData6, useQuery as useQuery10 } from "@tanstack/react-query";
|
|
2234
3106
|
|
|
2235
3107
|
// src/smart-route-refresh-policy.ts
|
|
2236
3108
|
var THIN_SMART_ROUTE_REFETCH_INTERVAL_MS = 5e3;
|
|
@@ -2370,7 +3242,7 @@ var getIsDocumentVisible = () => {
|
|
|
2370
3242
|
return document.visibilityState !== "hidden";
|
|
2371
3243
|
};
|
|
2372
3244
|
function useSmartRoute(options) {
|
|
2373
|
-
var _a, _b, _c, _d, _e, _f;
|
|
3245
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2374
3246
|
const client = useAggClient();
|
|
2375
3247
|
const {
|
|
2376
3248
|
venueMarketOutcomeId,
|
|
@@ -2394,7 +3266,7 @@ function useSmartRoute(options) {
|
|
|
2394
3266
|
const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
|
|
2395
3267
|
const hasValidInput = (maxSpend != null ? maxSpend : 0) > 0 || (sellShares != null ? sellShares : 0) > 0;
|
|
2396
3268
|
const queryEnabled = enabled && !!resolvedVenueMarketOutcomeId && hasValidInput;
|
|
2397
|
-
const query =
|
|
3269
|
+
const query = useQuery10({
|
|
2398
3270
|
queryKey: [
|
|
2399
3271
|
"smart-route",
|
|
2400
3272
|
resolvedVenueMarketOutcomeId,
|
|
@@ -2407,8 +3279,11 @@ function useSmartRoute(options) {
|
|
|
2407
3279
|
slipCapBps != null ? slipCapBps : null,
|
|
2408
3280
|
compareVenues != null ? compareVenues : false,
|
|
2409
3281
|
deepEstimate != null ? deepEstimate : false,
|
|
2410
|
-
...balanceCacheScope ? [
|
|
2411
|
-
|
|
3282
|
+
...balanceCacheScope ? [
|
|
3283
|
+
(_b = balanceCacheScope.accountId) != null ? _b : null,
|
|
3284
|
+
(_d = (_c = balanceCacheScope.balanceKey) != null ? _c : balanceCacheScope.balanceVersion) != null ? _d : null
|
|
3285
|
+
] : [],
|
|
3286
|
+
...tradeSide === "sell" ? [(_e = sellCacheScope == null ? void 0 : sellCacheScope.accountId) != null ? _e : null, (_f = sellCacheScope == null ? void 0 : sellCacheScope.positionVersion) != null ? _f : null] : []
|
|
2412
3287
|
],
|
|
2413
3288
|
queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
|
|
2414
3289
|
return client.getSmartRoute(
|
|
@@ -2466,7 +3341,7 @@ function useSmartRoute(options) {
|
|
|
2466
3341
|
}
|
|
2467
3342
|
}
|
|
2468
3343
|
return {
|
|
2469
|
-
data: (
|
|
3344
|
+
data: (_g = query.data) != null ? _g : null,
|
|
2470
3345
|
isLoading: query.isLoading,
|
|
2471
3346
|
isFetching: query.isFetching,
|
|
2472
3347
|
error: error instanceof Error ? error : error ? new Error(String(error)) : null,
|
|
@@ -2476,7 +3351,7 @@ function useSmartRoute(options) {
|
|
|
2476
3351
|
}
|
|
2477
3352
|
|
|
2478
3353
|
// src/use-limit-order-venue-quotes.ts
|
|
2479
|
-
import { keepPreviousData as keepPreviousData7, useQueries as
|
|
3354
|
+
import { keepPreviousData as keepPreviousData7, useQueries as useQueries4, useQuery as useQuery11 } from "@tanstack/react-query";
|
|
2480
3355
|
var getIsDocumentVisible2 = () => {
|
|
2481
3356
|
if (typeof document === "undefined") return true;
|
|
2482
3357
|
return document.visibilityState !== "hidden";
|
|
@@ -2531,7 +3406,7 @@ var useLimitOrderVenueQuotes = (options) => {
|
|
|
2531
3406
|
const hasRequiredAccount = tradeSide === "buy" || Boolean(accountId);
|
|
2532
3407
|
const queryEnabled = enabled && hasValidInput && hasRequiredAccount;
|
|
2533
3408
|
const serializedChainBalances = chainBalances ? JSON.stringify(chainBalances) : null;
|
|
2534
|
-
const tickMetadataQuery =
|
|
3409
|
+
const tickMetadataQuery = useQuery11({
|
|
2535
3410
|
queryKey: ["orderbooks", marketId != null ? marketId : "__disabled__", "limit-order-ticks"],
|
|
2536
3411
|
queryFn: ({ signal }) => client.getOrderbooks({ venueMarketIds: [marketId] }, { signal }),
|
|
2537
3412
|
enabled: enabled && Boolean(marketId),
|
|
@@ -2540,7 +3415,7 @@ var useLimitOrderVenueQuotes = (options) => {
|
|
|
2540
3415
|
refetchOnWindowFocus: false,
|
|
2541
3416
|
retry: 1
|
|
2542
3417
|
});
|
|
2543
|
-
const queries =
|
|
3418
|
+
const queries = useQueries4({
|
|
2544
3419
|
queries: uniqueRequests.map((request) => ({
|
|
2545
3420
|
queryKey: [
|
|
2546
3421
|
"smart-route",
|
|
@@ -2622,7 +3497,7 @@ var useLimitOrderVenueQuotes = (options) => {
|
|
|
2622
3497
|
};
|
|
2623
3498
|
|
|
2624
3499
|
// src/use-venue-sell-quotes.ts
|
|
2625
|
-
import { useQueries as
|
|
3500
|
+
import { useQueries as useQueries5 } from "@tanstack/react-query";
|
|
2626
3501
|
var getIsDocumentVisible3 = () => {
|
|
2627
3502
|
if (typeof document === "undefined") return true;
|
|
2628
3503
|
return document.visibilityState !== "hidden";
|
|
@@ -2653,7 +3528,7 @@ var useVenueSellQuotes = (options) => {
|
|
|
2653
3528
|
refreshContext
|
|
2654
3529
|
} = options;
|
|
2655
3530
|
const uniqueRequests = getUniqueVenueRequests2(requests);
|
|
2656
|
-
const queries =
|
|
3531
|
+
const queries = useQueries5({
|
|
2657
3532
|
queries: uniqueRequests.map((request) => {
|
|
2658
3533
|
const hasValidInput = request.requestedSellShares > 0 && request.sellShares > 0 && request.availableShares > 0;
|
|
2659
3534
|
const queryEnabled = enabled && !!venueMarketOutcomeId && !!accountId && hasValidInput;
|
|
@@ -2768,13 +3643,13 @@ function useUserHoldings(options) {
|
|
|
2768
3643
|
}
|
|
2769
3644
|
|
|
2770
3645
|
// src/use-enriched-venue-event.ts
|
|
2771
|
-
import { useMemo as
|
|
3646
|
+
import { useMemo as useMemo11 } from "react";
|
|
2772
3647
|
|
|
2773
3648
|
// src/use-venue-event.ts
|
|
2774
|
-
import { useQuery as
|
|
3649
|
+
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
2775
3650
|
|
|
2776
3651
|
// src/use-recurring-crypto-markets.ts
|
|
2777
|
-
import { useQuery as
|
|
3652
|
+
import { useQuery as useQuery12 } from "@tanstack/react-query";
|
|
2778
3653
|
var RESOLVING_POLL_INTERVAL_MS = 15e3;
|
|
2779
3654
|
var FALLBACK_VENUE_EVENT_PAGE_LIMIT = 100;
|
|
2780
3655
|
var FALLBACK_VENUE_EVENT_MAX_PAGES = 5;
|
|
@@ -3274,7 +4149,7 @@ var useRecurringCryptoMarkets = ({
|
|
|
3274
4149
|
const client = useAggClient();
|
|
3275
4150
|
const identity = event ? resolveRecurringCryptoIdentity(event) : null;
|
|
3276
4151
|
const isEnabled = enabled && event != null && identity != null;
|
|
3277
|
-
const query =
|
|
4152
|
+
const query = useQuery12({
|
|
3278
4153
|
queryKey: [
|
|
3279
4154
|
"recurring-crypto-markets",
|
|
3280
4155
|
event == null ? void 0 : event.id,
|
|
@@ -3336,7 +4211,7 @@ function useVenueEvent(options) {
|
|
|
3336
4211
|
var _a;
|
|
3337
4212
|
const client = useAggClient();
|
|
3338
4213
|
const { eventId, enabled = true, cluster } = options;
|
|
3339
|
-
const query =
|
|
4214
|
+
const query = useQuery13({
|
|
3340
4215
|
queryKey: ["venue-event", eventId, cluster === false ? "no-cluster" : ""],
|
|
3341
4216
|
queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
|
|
3342
4217
|
return client.getVenueEventById(eventId, { signal, cluster });
|
|
@@ -3357,7 +4232,7 @@ function useVenueEvent(options) {
|
|
|
3357
4232
|
|
|
3358
4233
|
// src/use-venue-markets.ts
|
|
3359
4234
|
import { QueryClient as QueryClient2, QueryClientContext as QueryClientContext2, useInfiniteQuery as useInfiniteQuery7 } from "@tanstack/react-query";
|
|
3360
|
-
import { useContext as useContext3, useEffect as
|
|
4235
|
+
import { useContext as useContext3, useEffect as useEffect10, useState as useState8 } from "react";
|
|
3361
4236
|
function useVenueMarkets(options) {
|
|
3362
4237
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3363
4238
|
const client = useContext3(AggClientContext);
|
|
@@ -3379,7 +4254,7 @@ function useVenueMarkets(options) {
|
|
|
3379
4254
|
const sortBy = options == null ? void 0 : options.sortBy;
|
|
3380
4255
|
const sortDir = options == null ? void 0 : options.sortDir;
|
|
3381
4256
|
const context = options == null ? void 0 : options.context;
|
|
3382
|
-
|
|
4257
|
+
useEffect10(() => {
|
|
3383
4258
|
if (queryClient) return void 0;
|
|
3384
4259
|
fallbackQueryClient.mount();
|
|
3385
4260
|
return () => {
|
|
@@ -3409,28 +4284,31 @@ function useVenueMarkets(options) {
|
|
|
3409
4284
|
sortDir != null ? sortDir : "",
|
|
3410
4285
|
context != null ? context : ""
|
|
3411
4286
|
],
|
|
3412
|
-
queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
|
|
4287
|
+
queryFn: (_0) => __async(null, [_0], function* ({ pageParam, signal }) {
|
|
3413
4288
|
if (!client) {
|
|
3414
4289
|
throw new Error("useVenueMarkets must be used within an <AggProvider>");
|
|
3415
4290
|
}
|
|
3416
|
-
const res = yield client.getVenueMarkets(
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
4291
|
+
const res = yield client.getVenueMarkets(
|
|
4292
|
+
{
|
|
4293
|
+
venue,
|
|
4294
|
+
venueEventId,
|
|
4295
|
+
cluster,
|
|
4296
|
+
search,
|
|
4297
|
+
matchStatus,
|
|
4298
|
+
status,
|
|
4299
|
+
aggKey,
|
|
4300
|
+
sportsMarketType,
|
|
4301
|
+
period,
|
|
4302
|
+
marketCategory,
|
|
4303
|
+
marketGroup,
|
|
4304
|
+
limit,
|
|
4305
|
+
cursor: pageParam,
|
|
4306
|
+
sortBy,
|
|
4307
|
+
sortDir,
|
|
4308
|
+
context
|
|
4309
|
+
},
|
|
4310
|
+
{ signal }
|
|
4311
|
+
);
|
|
3434
4312
|
return res;
|
|
3435
4313
|
}),
|
|
3436
4314
|
initialPageParam: void 0,
|
|
@@ -3447,10 +4325,10 @@ function useVenueMarkets(options) {
|
|
|
3447
4325
|
const hasNextPage = !!query.hasNextPage;
|
|
3448
4326
|
const { fetchNextPage, isFetchingNextPage } = query;
|
|
3449
4327
|
const fetchAll = (_j = options == null ? void 0 : options.fetchAll) != null ? _j : false;
|
|
3450
|
-
|
|
3451
|
-
if (!fetchAll || !hasNextPage || isFetchingNextPage) return;
|
|
4328
|
+
useEffect10(() => {
|
|
4329
|
+
if (!enabled || !client || !fetchAll || !hasNextPage || isFetchingNextPage) return;
|
|
3452
4330
|
void fetchNextPage();
|
|
3453
|
-
}, [fetchAll, hasNextPage, isFetchingNextPage, fetchNextPage]);
|
|
4331
|
+
}, [enabled, client, fetchAll, hasNextPage, isFetchingNextPage, fetchNextPage]);
|
|
3454
4332
|
return __spreadProps(__spreadValues({}, query), {
|
|
3455
4333
|
markets,
|
|
3456
4334
|
hasNextPage
|
|
@@ -3473,7 +4351,7 @@ function useEnrichedVenueEvent(options) {
|
|
|
3473
4351
|
const _a = useVenueEvent(options), { event, isLoading, error } = _a, rest = __objRest(_a, ["event", "isLoading", "error"]);
|
|
3474
4352
|
const eventEndedAt = (event == null ? void 0 : event.endDate) && Number.isFinite(Date.parse(event.endDate)) ? Date.parse(event.endDate) : null;
|
|
3475
4353
|
const shouldFetchOnlyOpenMarkets = eventEndedAt == null || eventEndedAt >= Date.now();
|
|
3476
|
-
const
|
|
4354
|
+
const openQuery = useVenueMarkets({
|
|
3477
4355
|
venueEventId: options.eventId,
|
|
3478
4356
|
cluster: options.cluster,
|
|
3479
4357
|
enabled: ((_b = options.enabled) != null ? _b : true) && !!event,
|
|
@@ -3483,10 +4361,11 @@ function useEnrichedVenueEvent(options) {
|
|
|
3483
4361
|
// MarketDetailsList (including limit, part of the query key) preserves the
|
|
3484
4362
|
// shared React Query cache key and the event-type ordering.
|
|
3485
4363
|
limit: 100,
|
|
3486
|
-
fetchAll:
|
|
4364
|
+
fetchAll: !options.progressive
|
|
3487
4365
|
});
|
|
4366
|
+
const { markets: openMarkets, isLoading: isEnrichingOpenMarkets } = openQuery;
|
|
3488
4367
|
const shouldFetchAllMarketsFallback = ((_c = options.enabled) != null ? _c : true) && !!event && shouldFetchOnlyOpenMarkets && !isEnrichingOpenMarkets && openMarkets.length === 0;
|
|
3489
|
-
const
|
|
4368
|
+
const fallbackQuery = useVenueMarkets({
|
|
3490
4369
|
venueEventId: options.eventId,
|
|
3491
4370
|
cluster: options.cluster,
|
|
3492
4371
|
enabled: shouldFetchAllMarketsFallback,
|
|
@@ -3494,11 +4373,13 @@ function useEnrichedVenueEvent(options) {
|
|
|
3494
4373
|
// closed/resolved markets, still render the event page instead of the
|
|
3495
4374
|
// unavailable state.
|
|
3496
4375
|
limit: 100,
|
|
3497
|
-
fetchAll:
|
|
4376
|
+
fetchAll: !options.progressive
|
|
3498
4377
|
});
|
|
4378
|
+
const { markets: fallbackMarkets, isLoading: isEnrichingFallbackMarkets } = fallbackQuery;
|
|
4379
|
+
const activeQuery = shouldFetchAllMarketsFallback ? fallbackQuery : openQuery;
|
|
3499
4380
|
const markets = fallbackMarkets.length > 0 ? fallbackMarkets : openMarkets;
|
|
3500
4381
|
const isEnriching = isEnrichingOpenMarkets || isEnrichingFallbackMarkets;
|
|
3501
|
-
const enrichedEvent =
|
|
4382
|
+
const enrichedEvent = useMemo11(() => {
|
|
3502
4383
|
if (!event) return void 0;
|
|
3503
4384
|
if (markets.length === 0) return event;
|
|
3504
4385
|
return mergeEventWithFullMarkets(event, markets);
|
|
@@ -3507,6 +4388,9 @@ function useEnrichedVenueEvent(options) {
|
|
|
3507
4388
|
event: enrichedEvent,
|
|
3508
4389
|
isLoading,
|
|
3509
4390
|
isEnriching,
|
|
4391
|
+
hasMoreMarkets: !!activeQuery.hasNextPage,
|
|
4392
|
+
loadMoreMarkets: activeQuery.fetchNextPage,
|
|
4393
|
+
isLoadingMoreMarkets: !!activeQuery.isFetchingNextPage,
|
|
3510
4394
|
error
|
|
3511
4395
|
});
|
|
3512
4396
|
}
|
|
@@ -3518,7 +4402,7 @@ import {
|
|
|
3518
4402
|
keepPreviousData as keepPreviousData8,
|
|
3519
4403
|
useInfiniteQuery as useInfiniteQuery8
|
|
3520
4404
|
} from "@tanstack/react-query";
|
|
3521
|
-
import { useContext as useContext4, useEffect as
|
|
4405
|
+
import { useContext as useContext4, useEffect as useEffect11, useMemo as useMemo12, useRef as useRef7, useState as useState9 } from "react";
|
|
3522
4406
|
function useVenueEvents(options) {
|
|
3523
4407
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3524
4408
|
const client = useContext4(AggClientContext);
|
|
@@ -3540,7 +4424,7 @@ function useVenueEvents(options) {
|
|
|
3540
4424
|
const endDateFrom = options == null ? void 0 : options.endDateFrom;
|
|
3541
4425
|
const grouped = options == null ? void 0 : options.grouped;
|
|
3542
4426
|
const initialPages = options == null ? void 0 : options.initialPages;
|
|
3543
|
-
|
|
4427
|
+
useEffect11(() => {
|
|
3544
4428
|
if (queryClient) return void 0;
|
|
3545
4429
|
fallbackQueryClient.mount();
|
|
3546
4430
|
return () => {
|
|
@@ -3568,7 +4452,7 @@ function useVenueEvents(options) {
|
|
|
3568
4452
|
grouped != null ? grouped : false,
|
|
3569
4453
|
limit
|
|
3570
4454
|
],
|
|
3571
|
-
queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
|
|
4455
|
+
queryFn: (_0) => __async(null, [_0], function* ({ pageParam, signal }) {
|
|
3572
4456
|
if (!client) {
|
|
3573
4457
|
throw new Error("useVenueEvents must be used within an <AggProvider>");
|
|
3574
4458
|
}
|
|
@@ -3586,7 +4470,8 @@ function useVenueEvents(options) {
|
|
|
3586
4470
|
maxYesPrice,
|
|
3587
4471
|
endDateFrom,
|
|
3588
4472
|
grouped,
|
|
3589
|
-
cursor: pageParam
|
|
4473
|
+
cursor: pageParam,
|
|
4474
|
+
signal
|
|
3590
4475
|
});
|
|
3591
4476
|
return res;
|
|
3592
4477
|
}),
|
|
@@ -3602,12 +4487,13 @@ function useVenueEvents(options) {
|
|
|
3602
4487
|
},
|
|
3603
4488
|
queryClient != null ? queryClient : fallbackQueryClient
|
|
3604
4489
|
);
|
|
3605
|
-
const prefetchedRef =
|
|
3606
|
-
|
|
4490
|
+
const prefetchedRef = useRef7(false);
|
|
4491
|
+
useEffect11(() => {
|
|
3607
4492
|
var _a2, _b2;
|
|
4493
|
+
if (!enabled || !client) return;
|
|
3608
4494
|
if (prefetchedRef.current) return;
|
|
3609
4495
|
if (!initialPages || initialPages <= 1) return;
|
|
3610
|
-
if (query.isLoading) return;
|
|
4496
|
+
if (query.isLoading || query.isFetching || query.isError || query.isPlaceholderData) return;
|
|
3611
4497
|
const pagesLoaded = (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.length) != null ? _b2 : 0;
|
|
3612
4498
|
if (pagesLoaded >= initialPages || !query.hasNextPage) {
|
|
3613
4499
|
prefetchedRef.current = true;
|
|
@@ -3615,13 +4501,18 @@ function useVenueEvents(options) {
|
|
|
3615
4501
|
}
|
|
3616
4502
|
void query.fetchNextPage();
|
|
3617
4503
|
}, [
|
|
4504
|
+
enabled,
|
|
4505
|
+
client,
|
|
3618
4506
|
initialPages,
|
|
3619
4507
|
query.isLoading,
|
|
4508
|
+
query.isFetching,
|
|
4509
|
+
query.isError,
|
|
4510
|
+
query.isPlaceholderData,
|
|
3620
4511
|
(_h = query.data) == null ? void 0 : _h.pages.length,
|
|
3621
4512
|
query.hasNextPage,
|
|
3622
4513
|
query.fetchNextPage
|
|
3623
4514
|
]);
|
|
3624
|
-
const events =
|
|
4515
|
+
const events = useMemo12(
|
|
3625
4516
|
() => {
|
|
3626
4517
|
var _a2, _b2;
|
|
3627
4518
|
return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
|
|
@@ -3639,7 +4530,7 @@ function useVenueEvents(options) {
|
|
|
3639
4530
|
}
|
|
3640
4531
|
|
|
3641
4532
|
// src/use-sports-live.ts
|
|
3642
|
-
import { useQuery as
|
|
4533
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
3643
4534
|
var SPORTS_LIVE_POLL_INTERVAL_MS = 5e3;
|
|
3644
4535
|
var SPORTS_SCHEDULED_POLL_INTERVAL_MS = 3e4;
|
|
3645
4536
|
var sportsLiveQueryKey = (sortedEventIds) => ["sports-live", ...sortedEventIds];
|
|
@@ -3659,7 +4550,7 @@ var useSportsLive = (eventIds, enabled = true) => {
|
|
|
3659
4550
|
const sortedEventIds = [
|
|
3660
4551
|
...new Set(eventIds.map((eventId) => eventId.trim()).filter(Boolean))
|
|
3661
4552
|
].sort();
|
|
3662
|
-
const query =
|
|
4553
|
+
const query = useQuery14({
|
|
3663
4554
|
queryKey: sportsLiveQueryKey(sortedEventIds),
|
|
3664
4555
|
queryFn: ({ signal }) => client.getSportsLive(sortedEventIds, { signal }),
|
|
3665
4556
|
enabled: enabled && sortedEventIds.length > 0,
|
|
@@ -3679,7 +4570,7 @@ var useSportsLive = (eventIds, enabled = true) => {
|
|
|
3679
4570
|
};
|
|
3680
4571
|
|
|
3681
4572
|
// src/use-venue-market-midpoints.ts
|
|
3682
|
-
import { keepPreviousData as keepPreviousData9, useQuery as
|
|
4573
|
+
import { keepPreviousData as keepPreviousData9, useQuery as useQuery15 } from "@tanstack/react-query";
|
|
3683
4574
|
var normalizeVenueMarketIds2 = (venueMarketIds) => {
|
|
3684
4575
|
return [
|
|
3685
4576
|
...new Set(venueMarketIds.map((venueMarketId) => venueMarketId.trim()).filter(Boolean))
|
|
@@ -3718,7 +4609,7 @@ function useVenueMarketMidpoints(options) {
|
|
|
3718
4609
|
const enabled = (_a = options.enabled) != null ? _a : true;
|
|
3719
4610
|
const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
|
|
3720
4611
|
const maxMidpointIdsPerRequest = (_b = options.maxMidpointIdsPerRequest) != null ? _b : configuredMaxMidpointIdsPerRequest;
|
|
3721
|
-
const query =
|
|
4612
|
+
const query = useQuery15({
|
|
3722
4613
|
queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds, maxMidpointIdsPerRequest] : ["venue-market-midpoints", "__disabled__"],
|
|
3723
4614
|
queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
|
|
3724
4615
|
if (requestedVenueMarketIds.length === 0) {
|
|
@@ -3794,7 +4685,7 @@ var computePriceGaps = ({
|
|
|
3794
4685
|
};
|
|
3795
4686
|
|
|
3796
4687
|
// src/use-viewport-midpoints.ts
|
|
3797
|
-
import { useEffect as
|
|
4688
|
+
import { useEffect as useEffect12, useMemo as useMemo13, useRef as useRef8, useState as useState10 } from "react";
|
|
3798
4689
|
var buildOutcomeMidpointMap = (outcomes) => {
|
|
3799
4690
|
const m = /* @__PURE__ */ new Map();
|
|
3800
4691
|
if (!outcomes) return m;
|
|
@@ -3848,14 +4739,14 @@ function useViewportMidpoints(visibleMarkets, options) {
|
|
|
3848
4739
|
} = useAggUiConfig();
|
|
3849
4740
|
const maxMidpointIdsPerRequest = (_a = options == null ? void 0 : options.maxMidpointIdsPerRequest) != null ? _a : configuredMaxMidpointIdsPerRequest;
|
|
3850
4741
|
const [cache, setCache] = useState10(() => /* @__PURE__ */ new Map());
|
|
3851
|
-
const inFlightRef =
|
|
3852
|
-
const visibleRef =
|
|
4742
|
+
const inFlightRef = useRef8(/* @__PURE__ */ new Set());
|
|
4743
|
+
const visibleRef = useRef8(visibleMarkets);
|
|
3853
4744
|
visibleRef.current = visibleMarkets;
|
|
3854
|
-
const visibleFp =
|
|
4745
|
+
const visibleFp = useMemo13(
|
|
3855
4746
|
() => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
|
|
3856
4747
|
[visibleMarkets]
|
|
3857
4748
|
);
|
|
3858
|
-
|
|
4749
|
+
useEffect12(() => {
|
|
3859
4750
|
const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
|
|
3860
4751
|
if (!toFetch.length) return;
|
|
3861
4752
|
let cancelled = false;
|
|
@@ -3879,7 +4770,7 @@ function useViewportMidpoints(visibleMarkets, options) {
|
|
|
3879
4770
|
cancelled = true;
|
|
3880
4771
|
};
|
|
3881
4772
|
}, [visibleFp, cache, maxMidpointIdsPerRequest]);
|
|
3882
|
-
const { prices, venueByOutcomeId } =
|
|
4773
|
+
const { prices, venueByOutcomeId } = useMemo13(() => {
|
|
3883
4774
|
var _a2, _b, _c, _d;
|
|
3884
4775
|
const map = /* @__PURE__ */ new Map();
|
|
3885
4776
|
const venueMap = /* @__PURE__ */ new Map();
|
|
@@ -3912,15 +4803,15 @@ function useViewportMidpoints(visibleMarkets, options) {
|
|
|
3912
4803
|
}
|
|
3913
4804
|
|
|
3914
4805
|
// src/use-visible-ids.ts
|
|
3915
|
-
import { useCallback as useCallback7, useEffect as
|
|
4806
|
+
import { useCallback as useCallback7, useEffect as useEffect13, useRef as useRef9, useState as useState11 } from "react";
|
|
3916
4807
|
function useVisibleIds(options = {}) {
|
|
3917
4808
|
const { rootMargin = "0px", threshold = 0 } = options;
|
|
3918
4809
|
const [visibleIds, setVisibleIds] = useState11(() => /* @__PURE__ */ new Set());
|
|
3919
|
-
const observerRef =
|
|
3920
|
-
const elementsRef =
|
|
3921
|
-
const elementIdRef =
|
|
3922
|
-
const callbackRefsRef =
|
|
3923
|
-
|
|
4810
|
+
const observerRef = useRef9(null);
|
|
4811
|
+
const elementsRef = useRef9(/* @__PURE__ */ new Map());
|
|
4812
|
+
const elementIdRef = useRef9(/* @__PURE__ */ new WeakMap());
|
|
4813
|
+
const callbackRefsRef = useRef9(/* @__PURE__ */ new Map());
|
|
4814
|
+
useEffect13(() => {
|
|
3924
4815
|
if (typeof IntersectionObserver === "undefined") return;
|
|
3925
4816
|
const observer = new IntersectionObserver(
|
|
3926
4817
|
(entries) => {
|
|
@@ -3985,7 +4876,7 @@ function useVisibleIds(options = {}) {
|
|
|
3985
4876
|
}
|
|
3986
4877
|
|
|
3987
4878
|
// src/use-paper-onboarding.ts
|
|
3988
|
-
import { useCallback as useCallback8, useEffect as
|
|
4879
|
+
import { useCallback as useCallback8, useEffect as useEffect14, useState as useState12 } from "react";
|
|
3989
4880
|
var STORAGE_KEY = "agg_paper_onboarding_seen";
|
|
3990
4881
|
var isBrowser = () => typeof window !== "undefined" && "localStorage" in window;
|
|
3991
4882
|
var seenKey = (userId) => `${STORAGE_KEY}:${userId}`;
|
|
@@ -4010,14 +4901,14 @@ function usePaperOnboarding() {
|
|
|
4010
4901
|
const userId = user == null ? void 0 : user.id;
|
|
4011
4902
|
const [dismissed, setDismissed] = useState12(false);
|
|
4012
4903
|
const [seen, setSeen] = useState12(null);
|
|
4013
|
-
|
|
4904
|
+
useEffect14(() => {
|
|
4014
4905
|
if (!userId) {
|
|
4015
4906
|
setSeen(null);
|
|
4016
4907
|
return;
|
|
4017
4908
|
}
|
|
4018
4909
|
setSeen(hasSeen(userId));
|
|
4019
4910
|
}, [userId]);
|
|
4020
|
-
|
|
4911
|
+
useEffect14(() => {
|
|
4021
4912
|
setDismissed(false);
|
|
4022
4913
|
}, [userId]);
|
|
4023
4914
|
const dismiss = useCallback8(() => {
|
|
@@ -4027,6 +4918,206 @@ function usePaperOnboarding() {
|
|
|
4027
4918
|
const isOpen = isPaperMode && !isResolving && isAuthenticated && Boolean(userId) && seen === false && !dismissed;
|
|
4028
4919
|
return { isOpen, dismiss };
|
|
4029
4920
|
}
|
|
4921
|
+
|
|
4922
|
+
// src/use-settlement-details-data.ts
|
|
4923
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
4924
|
+
function useSettlementDetailsData(options) {
|
|
4925
|
+
const client = useAggClient();
|
|
4926
|
+
const { eventId, market, enabled, needsEvent, needsMarket } = options;
|
|
4927
|
+
const eventQuery = useQuery16({
|
|
4928
|
+
queryKey: ["settlement-details", "event", client.appId, eventId],
|
|
4929
|
+
queryFn: ({ signal }) => client.getVenueEventById(eventId, { signal }),
|
|
4930
|
+
enabled: enabled && needsEvent,
|
|
4931
|
+
staleTime: 5 * 6e4,
|
|
4932
|
+
gcTime: 10 * 6e4,
|
|
4933
|
+
retry: false
|
|
4934
|
+
});
|
|
4935
|
+
const marketQuery = useQuery16({
|
|
4936
|
+
queryKey: ["settlement-details", "market", client.appId, market.id],
|
|
4937
|
+
queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
|
|
4938
|
+
const response = yield client.getVenueMarkets(
|
|
4939
|
+
{ venue: market.venue, externalIdentifier: [market.externalIdentifier], limit: 1 },
|
|
4940
|
+
{ signal }
|
|
4941
|
+
);
|
|
4942
|
+
const selected = response.data.find((candidate) => candidate.id === market.id);
|
|
4943
|
+
if (!selected) throw new Error("Selected market details unavailable");
|
|
4944
|
+
return { selected, markets: response.data };
|
|
4945
|
+
}),
|
|
4946
|
+
enabled: enabled && needsMarket,
|
|
4947
|
+
staleTime: 5 * 6e4,
|
|
4948
|
+
gcTime: 10 * 6e4,
|
|
4949
|
+
retry: false
|
|
4950
|
+
});
|
|
4951
|
+
return { eventQuery, marketQuery };
|
|
4952
|
+
}
|
|
4953
|
+
|
|
4954
|
+
// src/use-hosted-venue-transfers.ts
|
|
4955
|
+
import { useEffect as useEffect15, useRef as useRef10, useState as useState13 } from "react";
|
|
4956
|
+
import { useMutation as useMutation2, useQuery as useQuery17, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
4957
|
+
var validRequest = (value) => {
|
|
4958
|
+
var _a;
|
|
4959
|
+
const row = value;
|
|
4960
|
+
return !!row && ((_a = row.request) == null ? void 0 : _a.mode) === "live" && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
|
|
4961
|
+
row.request.requestId
|
|
4962
|
+
) && /^[1-9][0-9]{0,31}$/.test(row.request.amountRaw) && /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(row.request.destinationAddress) && (row.withdrawalId === void 0 || /^[a-zA-Z0-9_-]{1,256}$/.test(row.withdrawalId));
|
|
4963
|
+
};
|
|
4964
|
+
function useHostedVenueTransfers(accountId, environment) {
|
|
4965
|
+
var _a, _b, _c, _d, _e;
|
|
4966
|
+
const client = useAggClient();
|
|
4967
|
+
const { user, isAuthenticated } = useAggAuthContext();
|
|
4968
|
+
const { executionMode, isResolving } = useResolvedExecutionMode();
|
|
4969
|
+
const queryClient = useQueryClient4();
|
|
4970
|
+
const userId = (_a = user == null ? void 0 : user.id) != null ? _a : null;
|
|
4971
|
+
const permitted = isAuthenticated && !!userId && !isResolving && executionMode === "live";
|
|
4972
|
+
const scope = JSON.stringify([userId, accountId, environment]);
|
|
4973
|
+
const storageKey = "agg:betdex-withdrawal:" + scope;
|
|
4974
|
+
const [entry, setEntry] = useState13({
|
|
4975
|
+
scope: "",
|
|
4976
|
+
ready: false,
|
|
4977
|
+
journal: null,
|
|
4978
|
+
invalid: false
|
|
4979
|
+
});
|
|
4980
|
+
const session = useRef10({ client, scope, permitted });
|
|
4981
|
+
session.current = { client, scope, permitted };
|
|
4982
|
+
const mounted = useRef10(true);
|
|
4983
|
+
const dispatching = useRef10(false);
|
|
4984
|
+
const intent = useRef10(null);
|
|
4985
|
+
const current = entry.scope === scope ? entry : null;
|
|
4986
|
+
const journal = (_b = current == null ? void 0 : current.journal) != null ? _b : null;
|
|
4987
|
+
const assertSession = () => {
|
|
4988
|
+
if (!mounted.current || !permitted || !session.current.permitted || session.current.client !== client || session.current.scope !== scope)
|
|
4989
|
+
throw new Error("Hosted transfers are unavailable for this session");
|
|
4990
|
+
};
|
|
4991
|
+
const save = (next) => {
|
|
4992
|
+
localStorage.setItem(storageKey, JSON.stringify(next));
|
|
4993
|
+
if (mounted.current && session.current.scope === scope) {
|
|
4994
|
+
intent.current = { scope, journal: next };
|
|
4995
|
+
setEntry({ scope, ready: true, journal: next, invalid: false });
|
|
4996
|
+
}
|
|
4997
|
+
};
|
|
4998
|
+
const assertResult = (result2) => {
|
|
4999
|
+
if (result2.accountId !== accountId || result2.environment !== environment)
|
|
5000
|
+
throw new Error("Hosted transfer identity mismatch");
|
|
5001
|
+
};
|
|
5002
|
+
const invalidate = () => {
|
|
5003
|
+
void queryClient.invalidateQueries({
|
|
5004
|
+
queryKey: hostedVenueAccountQueryKeys.account("betdex", userId, "live")
|
|
5005
|
+
});
|
|
5006
|
+
invalidateBalanceQueries(queryClient);
|
|
5007
|
+
};
|
|
5008
|
+
const deposit = useMutation2({
|
|
5009
|
+
mutationFn: () => __async(null, null, function* () {
|
|
5010
|
+
assertSession();
|
|
5011
|
+
const result2 = yield client.getHostedVenueDepositAddress("betdex", { mode: "live" });
|
|
5012
|
+
assertResult(result2);
|
|
5013
|
+
assertSession();
|
|
5014
|
+
return { scope, result: result2 };
|
|
5015
|
+
}),
|
|
5016
|
+
retry: false
|
|
5017
|
+
});
|
|
5018
|
+
const withdrawal = useMutation2({
|
|
5019
|
+
mutationFn: (request) => __async(null, null, function* () {
|
|
5020
|
+
assertSession();
|
|
5021
|
+
if (dispatching.current) throw new Error("Withdrawal request is already pending");
|
|
5022
|
+
dispatching.current = true;
|
|
5023
|
+
try {
|
|
5024
|
+
save(request);
|
|
5025
|
+
const result2 = request.withdrawalId ? yield client.getHostedVenueWithdrawal("betdex", request.withdrawalId, { mode: "live" }) : yield client.withdrawHostedVenue("betdex", request.request);
|
|
5026
|
+
assertResult(result2);
|
|
5027
|
+
save(__spreadProps(__spreadValues({}, request), { withdrawalId: result2.id }));
|
|
5028
|
+
assertSession();
|
|
5029
|
+
invalidate();
|
|
5030
|
+
return { scope, result: result2 };
|
|
5031
|
+
} finally {
|
|
5032
|
+
dispatching.current = false;
|
|
5033
|
+
}
|
|
5034
|
+
}),
|
|
5035
|
+
retry: false
|
|
5036
|
+
});
|
|
5037
|
+
const status = useQuery17({
|
|
5038
|
+
queryKey: ["agg", "hosted-venue-withdrawal", scope, journal == null ? void 0 : journal.withdrawalId],
|
|
5039
|
+
queryFn: () => __async(null, null, function* () {
|
|
5040
|
+
assertSession();
|
|
5041
|
+
if (!(journal == null ? void 0 : journal.withdrawalId)) throw new Error("Withdrawal identity is unavailable");
|
|
5042
|
+
const result2 = yield client.getHostedVenueWithdrawal("betdex", journal.withdrawalId, {
|
|
5043
|
+
mode: "live"
|
|
5044
|
+
});
|
|
5045
|
+
assertResult(result2);
|
|
5046
|
+
assertSession();
|
|
5047
|
+
if (result2.status === "confirmed" || result2.status === "failed") invalidate();
|
|
5048
|
+
return result2;
|
|
5049
|
+
}),
|
|
5050
|
+
enabled: permitted && !!(journal == null ? void 0 : journal.withdrawalId),
|
|
5051
|
+
retry: false,
|
|
5052
|
+
refetchInterval: (query) => {
|
|
5053
|
+
var _a2;
|
|
5054
|
+
return ((_a2 = query.state.data) == null ? void 0 : _a2.status) === "processing" ? 2e3 : false;
|
|
5055
|
+
},
|
|
5056
|
+
refetchIntervalInBackground: false
|
|
5057
|
+
});
|
|
5058
|
+
useEffect15(() => {
|
|
5059
|
+
mounted.current = true;
|
|
5060
|
+
return () => {
|
|
5061
|
+
mounted.current = false;
|
|
5062
|
+
};
|
|
5063
|
+
}, []);
|
|
5064
|
+
const resetDeposit = deposit.reset;
|
|
5065
|
+
const resetWithdrawal = withdrawal.reset;
|
|
5066
|
+
useEffect15(() => {
|
|
5067
|
+
resetDeposit();
|
|
5068
|
+
resetWithdrawal();
|
|
5069
|
+
if (!permitted) return;
|
|
5070
|
+
try {
|
|
5071
|
+
const text = localStorage.getItem(storageKey);
|
|
5072
|
+
const value = text ? JSON.parse(text) : null;
|
|
5073
|
+
if (value !== null && !validRequest(value)) throw new Error("Invalid saved withdrawal");
|
|
5074
|
+
intent.current = value ? { scope, journal: value } : null;
|
|
5075
|
+
setEntry({ scope, ready: true, journal: value, invalid: false });
|
|
5076
|
+
} catch (e) {
|
|
5077
|
+
setEntry({ scope, ready: false, journal: null, invalid: true });
|
|
5078
|
+
}
|
|
5079
|
+
}, [storageKey, scope, permitted, resetDeposit, resetWithdrawal]);
|
|
5080
|
+
const result = (_d = status.data) != null ? _d : ((_c = withdrawal.data) == null ? void 0 : _c.scope) === scope ? withdrawal.data.result : void 0;
|
|
5081
|
+
const terminal = (result == null ? void 0 : result.status) === "confirmed" || (result == null ? void 0 : result.status) === "failed";
|
|
5082
|
+
return {
|
|
5083
|
+
isAvailable: permitted,
|
|
5084
|
+
ready: !!(current == null ? void 0 : current.ready),
|
|
5085
|
+
storageError: !!(current == null ? void 0 : current.invalid),
|
|
5086
|
+
deposit: __spreadProps(__spreadValues({}, deposit), { data: ((_e = deposit.data) == null ? void 0 : _e.scope) === scope ? deposit.data.result : void 0 }),
|
|
5087
|
+
withdrawal: __spreadProps(__spreadValues({}, withdrawal), { data: result, isError: withdrawal.isError || status.isError }),
|
|
5088
|
+
request: journal == null ? void 0 : journal.request,
|
|
5089
|
+
submit: (amountRaw, destinationAddress) => __async(null, null, function* () {
|
|
5090
|
+
var _a2;
|
|
5091
|
+
assertSession();
|
|
5092
|
+
if (!(current == null ? void 0 : current.ready) || current.invalid || journal || ((_a2 = intent.current) == null ? void 0 : _a2.scope) === scope)
|
|
5093
|
+
throw new Error("Resolve the existing withdrawal first");
|
|
5094
|
+
const request = {
|
|
5095
|
+
mode: "live",
|
|
5096
|
+
requestId: crypto.randomUUID(),
|
|
5097
|
+
amountRaw,
|
|
5098
|
+
destinationAddress
|
|
5099
|
+
};
|
|
5100
|
+
if (!validRequest({ request })) throw new Error("Invalid withdrawal request");
|
|
5101
|
+
save({ request });
|
|
5102
|
+
return withdrawal.mutateAsync({ request });
|
|
5103
|
+
}),
|
|
5104
|
+
check: () => __async(null, null, function* () {
|
|
5105
|
+
assertSession();
|
|
5106
|
+
if (!journal || !(current == null ? void 0 : current.ready)) throw new Error("No saved withdrawal");
|
|
5107
|
+
return withdrawal.mutateAsync(journal);
|
|
5108
|
+
}),
|
|
5109
|
+
clear: () => {
|
|
5110
|
+
var _a2;
|
|
5111
|
+
assertSession();
|
|
5112
|
+
if (!terminal || dispatching.current || ((_a2 = intent.current) == null ? void 0 : _a2.journal.withdrawalId) !== (result == null ? void 0 : result.id))
|
|
5113
|
+
throw new Error("Withdrawal is not terminal");
|
|
5114
|
+
localStorage.removeItem(storageKey);
|
|
5115
|
+
intent.current = null;
|
|
5116
|
+
setEntry({ scope, ready: true, journal: null, invalid: false });
|
|
5117
|
+
withdrawal.reset();
|
|
5118
|
+
}
|
|
5119
|
+
};
|
|
5120
|
+
}
|
|
4030
5121
|
export {
|
|
4031
5122
|
AUTH_CHOOSER_OPEN_EVENT,
|
|
4032
5123
|
AggBalanceProvider,
|
|
@@ -4037,6 +5128,7 @@ export {
|
|
|
4037
5128
|
CONFIRMED_MATCH_STATUSES,
|
|
4038
5129
|
DEFAULT_AGG_ROOT_CLASS_NAME,
|
|
4039
5130
|
EventListStateProvider,
|
|
5131
|
+
MAX_ORDER_VENUE_MARKET_IDS_PER_REQUEST,
|
|
4040
5132
|
MAX_PRICE_GAP_PCT,
|
|
4041
5133
|
MIN_PRICE_GAP_PCT,
|
|
4042
5134
|
MarketStatus,
|
|
@@ -4067,6 +5159,7 @@ export {
|
|
|
4067
5159
|
getVisibleVenueIdsByConfig,
|
|
4068
5160
|
getVisibleVenuesByConfig,
|
|
4069
5161
|
getWalletAddressFromUserProfile,
|
|
5162
|
+
hostedVenueAccountQueryKeys,
|
|
4070
5163
|
invalidateBalanceQueries,
|
|
4071
5164
|
invalidatePositionQueries,
|
|
4072
5165
|
invalidateUserActivityQueries,
|
|
@@ -4092,6 +5185,7 @@ export {
|
|
|
4092
5185
|
resolveRecurringCryptoTimeline,
|
|
4093
5186
|
resolveRollingWindow,
|
|
4094
5187
|
resolveTradingStateKind,
|
|
5188
|
+
retinaImageUrl,
|
|
4095
5189
|
sharedKycQueryKeys,
|
|
4096
5190
|
sortVenues,
|
|
4097
5191
|
sportsLiveQueryKey,
|
|
@@ -4123,10 +5217,14 @@ export {
|
|
|
4123
5217
|
useEventTradingContext,
|
|
4124
5218
|
useExecuteManaged,
|
|
4125
5219
|
useExecutionOrders,
|
|
5220
|
+
useExecutionOrdersForMarkets,
|
|
4126
5221
|
useExecutionPositions,
|
|
4127
5222
|
useExecutionProgress,
|
|
4128
5223
|
useExternalId,
|
|
4129
5224
|
useGeoBlock,
|
|
5225
|
+
useHostedVenueAccount,
|
|
5226
|
+
useHostedVenueActivity,
|
|
5227
|
+
useHostedVenueTransfers,
|
|
4130
5228
|
useLabels,
|
|
4131
5229
|
useLimitOrderVenueQuotes,
|
|
4132
5230
|
useLinkAccount,
|
|
@@ -4141,6 +5239,7 @@ export {
|
|
|
4141
5239
|
useManagedBalances,
|
|
4142
5240
|
useMarketArb,
|
|
4143
5241
|
useMarketChart,
|
|
5242
|
+
useMarketCharts,
|
|
4144
5243
|
useMarketOrderbook,
|
|
4145
5244
|
useMarketSearch,
|
|
4146
5245
|
useMidpoints,
|
|
@@ -4156,7 +5255,7 @@ export {
|
|
|
4156
5255
|
usePaperOnboarding,
|
|
4157
5256
|
usePlaceLimitOrder,
|
|
4158
5257
|
usePositions,
|
|
4159
|
-
|
|
5258
|
+
useQueryClient5 as useQueryClient,
|
|
4160
5259
|
useRampQuotes,
|
|
4161
5260
|
useRampSession,
|
|
4162
5261
|
useRecurringCryptoMarkets,
|
|
@@ -4169,6 +5268,7 @@ export {
|
|
|
4169
5268
|
useSdkLabels,
|
|
4170
5269
|
useSdkUiConfig,
|
|
4171
5270
|
useSearch,
|
|
5271
|
+
useSettlementDetailsData,
|
|
4172
5272
|
useSharedKyc,
|
|
4173
5273
|
useSmartRoute,
|
|
4174
5274
|
useSportsLive,
|