@agg-build/hooks 2.1.1 → 2.1.3

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/index.js CHANGED
@@ -90,11 +90,13 @@ __export(src_exports, {
90
90
  TradeSide: () => TradeSide,
91
91
  TurnstileChallengeError: () => import_sdk4.TurnstileChallengeError,
92
92
  Venue: () => Venue,
93
+ buildLiveBestPriceCandidates: () => buildLiveBestPriceCandidates,
93
94
  computeClosedPositionTotals: () => computeClosedPositionTotals,
94
95
  computePriceGaps: () => computePriceGaps,
95
96
  defaultAggUiConfig: () => defaultAggUiConfig,
96
97
  defaultSdkUiConfig: () => defaultAggUiConfig,
97
98
  executionKeys: () => executionKeys,
99
+ extractOutcomeBestCandidate: () => extractOutcomeBestCandidate,
98
100
  findLivePriceById: () => findLivePriceById,
99
101
  getBuilder: () => getBuilder,
100
102
  getDepositAddress: () => getDepositAddress,
@@ -156,6 +158,7 @@ __export(src_exports, {
156
158
  useGeoBlock: () => useGeoBlock,
157
159
  useLabels: () => useLabels,
158
160
  useLinkAccount: () => useLinkAccount,
161
+ useLiveBestPriceCandidates: () => useLiveBestPriceCandidates,
159
162
  useLiveBestPrices: () => useLiveBestPrices,
160
163
  useLiveCandleOverlay: () => useLiveCandleOverlay,
161
164
  useLiveCandles: () => useLiveCandles,
@@ -193,7 +196,6 @@ __export(src_exports, {
193
196
  useSearch: () => useSearch,
194
197
  useSmartRoute: () => useSmartRoute,
195
198
  useSyncBalances: () => useSyncBalances,
196
- useTradableVenues: () => useTradableVenues,
197
199
  useUserActivity: () => useUserActivity,
198
200
  useUserHoldings: () => useUserHoldings,
199
201
  useVenueEvent: () => useVenueEvent,
@@ -982,6 +984,8 @@ var enUsLabels = {
982
984
  showOutcomeAria: (label) => `Show ${label} outcome`,
983
985
  viewResolved: "View resolved",
984
986
  hideResolved: "Hide resolved",
987
+ resolvingTitle: "Resolving market\u2026",
988
+ resolvingDescription: "This market has closed. We're waiting for final settlement data and will update the result once it's confirmed on-chain.",
985
989
  volumeUnavailable: "Volume unavailable",
986
990
  tabs: {
987
991
  orderBook: "Order Book",
@@ -1155,6 +1159,7 @@ var enUsLabels = {
1155
1159
  orderSkip: "Skip",
1156
1160
  orderRetryRemaining: "Retry remaining",
1157
1161
  resolvedEarningsTitle: "Your Earnings",
1162
+ resolvedResolutionDateLabel: "Resolution date",
1158
1163
  resolvedSharesLabel: "Shares",
1159
1164
  resolvedTotalPayoutLabel: "Total payout",
1160
1165
  claimWinnings: "Claim Winnings",
@@ -1299,7 +1304,51 @@ var enUsLabels = {
1299
1304
  winningOutcome: (label) => `Winning outcome: ${label}`,
1300
1305
  resolvedOutcome: (label) => `Resolved: ${label}`,
1301
1306
  marketDetailsAriaByDate: (dateLabel) => `Market details for ${dateLabel}`,
1302
- marketDetailsAriaByQuestion: (question) => `Market details for ${question}`
1307
+ marketDetailsAriaByQuestion: (question) => `Market details for ${question}`,
1308
+ sports: {
1309
+ summaryAria: "Sports event summary",
1310
+ sectionTabsAria: "Sports market sections",
1311
+ lineSelectorAria: (marketTitle) => `Select line for ${marketTitle}`,
1312
+ previousLineAria: (marketTitle) => `Show previous lines for ${marketTitle}`,
1313
+ nextLineAria: (marketTitle) => `Show next lines for ${marketTitle}`,
1314
+ comparisonToggleAria: (marketTitle, expanded) => `${expanded ? "Hide" : "Show"} venue comparison for ${marketTitle}`,
1315
+ comparisonTitle: "Venue alternatives",
1316
+ compareVenues: (count) => `Compare ${count} venues`,
1317
+ marketCount: (count) => `${count} markets`,
1318
+ venueCount: (count) => `${count} venues`,
1319
+ volumeShort: "Vol.",
1320
+ totalVolumeShort: "Total Vol.",
1321
+ gameStarts: "Game starts",
1322
+ moreMarketsTitle: "More markets",
1323
+ gameLinesTab: "Game Lines",
1324
+ halvesTab: "Halves",
1325
+ exactScoreTab: "Exact Score",
1326
+ cornersTab: "Corners",
1327
+ goalsTab: "Goals",
1328
+ assistsTab: "Assists",
1329
+ shotsTab: "Shots",
1330
+ otherTab: "Other",
1331
+ moneylineTitle: "Moneyline",
1332
+ spreadTitle: "Spreads",
1333
+ totalTitle: "Totals",
1334
+ fullPeriod: "Regular time",
1335
+ firstHalfPeriod: "1st half",
1336
+ secondHalfPeriod: "2nd half",
1337
+ quarterOnePeriod: "1st quarter",
1338
+ quarterTwoPeriod: "2nd quarter",
1339
+ quarterThreePeriod: "3rd quarter",
1340
+ quarterFourPeriod: "4th quarter",
1341
+ overtimePeriod: "Overtime",
1342
+ otherPeriod: "Other",
1343
+ loadingTitle: "Loading section",
1344
+ loadingDescription: "Fetching the latest markets for this game.",
1345
+ emptyTitle: "No markets available",
1346
+ emptyDescription: (sectionLabel) => `There are no ${sectionLabel} markets yet.`,
1347
+ loadMore: "Load more",
1348
+ loadingMore: "Loading more",
1349
+ bestPriceBadge: "Best price",
1350
+ selectOutcomeAria: (marketTitle, outcomeLabel, priceLabel) => `Select ${outcomeLabel} in ${marketTitle} at ${priceLabel}`
1351
+ }
1303
1352
  },
1304
1353
  header: {
1305
1354
  bannerAria: "Site header",
@@ -1461,7 +1510,8 @@ var defaultAggUiConfig = {
1461
1510
  showFeesBreakdown: false,
1462
1511
  enableGradients: false,
1463
1512
  enableVenueEventDiscoveryFilters: false,
1464
- enableNotifications: true
1513
+ enableNotifications: true,
1514
+ showSportsMarkets: false
1465
1515
  },
1466
1516
  market: {
1467
1517
  arbitrageThreshold: 0,
@@ -1492,7 +1542,7 @@ var mergeAggUiSearchConfig = (config) => {
1492
1542
  };
1493
1543
  };
1494
1544
  var mergeAggUiConfig = (persisted, config) => {
1495
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X;
1545
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z;
1496
1546
  const locale = (_d = (_c = (_a = config == null ? void 0 : config.general) == null ? void 0 : _a.locale) != null ? _c : (_b = persisted.general) == null ? void 0 : _b.locale) != null ? _d : DEFAULT_LOCALE;
1497
1547
  const theme = (_h = (_g = (_e = config == null ? void 0 : config.general) == null ? void 0 : _e.theme) != null ? _g : (_f = persisted.general) == null ? void 0 : _f.theme) != null ? _h : defaultAggUiConfig.general.theme;
1498
1548
  const formatters = createFormatters(locale);
@@ -1514,27 +1564,28 @@ var mergeAggUiConfig = (persisted, config) => {
1514
1564
  showFeesBreakdown: (_v = (_u = config == null ? void 0 : config.features) == null ? void 0 : _u.showFeesBreakdown) != null ? _v : defaultAggUiConfig.features.showFeesBreakdown,
1515
1565
  enableGradients: (_x = (_w = config == null ? void 0 : config.features) == null ? void 0 : _w.enableGradients) != null ? _x : defaultAggUiConfig.features.enableGradients,
1516
1566
  enableVenueEventDiscoveryFilters: (_z = (_y = config == null ? void 0 : config.features) == null ? void 0 : _y.enableVenueEventDiscoveryFilters) != null ? _z : defaultAggUiConfig.features.enableVenueEventDiscoveryFilters,
1517
- enableNotifications: (_B = (_A = config == null ? void 0 : config.features) == null ? void 0 : _A.enableNotifications) != null ? _B : defaultAggUiConfig.features.enableNotifications
1567
+ enableNotifications: (_B = (_A = config == null ? void 0 : config.features) == null ? void 0 : _A.enableNotifications) != null ? _B : defaultAggUiConfig.features.enableNotifications,
1568
+ showSportsMarkets: (_D = (_C = config == null ? void 0 : config.features) == null ? void 0 : _C.showSportsMarkets) != null ? _D : defaultAggUiConfig.features.showSportsMarkets
1518
1569
  },
1519
1570
  market: {
1520
- arbitrageThreshold: (_D = (_C = config == null ? void 0 : config.market) == null ? void 0 : _C.arbitrageThreshold) != null ? _D : defaultAggUiConfig.market.arbitrageThreshold,
1521
- maxMidpointIdsPerRequest: (_F = (_E = config == null ? void 0 : config.market) == null ? void 0 : _E.maxMidpointIdsPerRequest) != null ? _F : defaultAggUiConfig.market.maxMidpointIdsPerRequest
1571
+ arbitrageThreshold: (_F = (_E = config == null ? void 0 : config.market) == null ? void 0 : _E.arbitrageThreshold) != null ? _F : defaultAggUiConfig.market.arbitrageThreshold,
1572
+ maxMidpointIdsPerRequest: (_H = (_G = config == null ? void 0 : config.market) == null ? void 0 : _G.maxMidpointIdsPerRequest) != null ? _H : defaultAggUiConfig.market.maxMidpointIdsPerRequest
1522
1573
  },
1523
1574
  chart: {
1524
- defaultChartTimeRange: (_H = (_G = config == null ? void 0 : config.chart) == null ? void 0 : _G.defaultChartTimeRange) != null ? _H : defaultAggUiConfig.chart.defaultChartTimeRange,
1525
- selectedChartTimeRange: (_L = (_K = (_I = persisted.chart) == null ? void 0 : _I.selectedChartTimeRange) != null ? _K : (_J = config == null ? void 0 : config.chart) == null ? void 0 : _J.defaultChartTimeRange) != null ? _L : defaultAggUiConfig.chart.defaultChartTimeRange,
1575
+ defaultChartTimeRange: (_J = (_I = config == null ? void 0 : config.chart) == null ? void 0 : _I.defaultChartTimeRange) != null ? _J : defaultAggUiConfig.chart.defaultChartTimeRange,
1576
+ selectedChartTimeRange: (_N = (_M = (_K = persisted.chart) == null ? void 0 : _K.selectedChartTimeRange) != null ? _M : (_L = config == null ? void 0 : config.chart) == null ? void 0 : _L.defaultChartTimeRange) != null ? _N : defaultAggUiConfig.chart.defaultChartTimeRange,
1526
1577
  setSelectedChartTimeRange: defaultAggUiConfig.chart.setSelectedChartTimeRange
1527
1578
  },
1528
1579
  formatting: {
1529
- formatNumber: (_N = (_M = config == null ? void 0 : config.formatting) == null ? void 0 : _M.formatNumber) != null ? _N : formatters.formatNumber,
1530
- formatPercent: (_P = (_O = config == null ? void 0 : config.formatting) == null ? void 0 : _O.formatPercent) != null ? _P : formatters.formatPercent,
1531
- formatCurrency: (_R = (_Q = config == null ? void 0 : config.formatting) == null ? void 0 : _Q.formatCurrency) != null ? _R : formatters.formatCurrency,
1532
- formatCompactCurrency: (_T = (_S = config == null ? void 0 : config.formatting) == null ? void 0 : _S.formatCompactCurrency) != null ? _T : formatters.formatCompactCurrency,
1533
- formatDate: (_V = (_U = config == null ? void 0 : config.formatting) == null ? void 0 : _U.formatDate) != null ? _V : formatters.formatDate
1580
+ formatNumber: (_P = (_O = config == null ? void 0 : config.formatting) == null ? void 0 : _O.formatNumber) != null ? _P : formatters.formatNumber,
1581
+ formatPercent: (_R = (_Q = config == null ? void 0 : config.formatting) == null ? void 0 : _Q.formatPercent) != null ? _R : formatters.formatPercent,
1582
+ formatCurrency: (_T = (_S = config == null ? void 0 : config.formatting) == null ? void 0 : _S.formatCurrency) != null ? _T : formatters.formatCurrency,
1583
+ formatCompactCurrency: (_V = (_U = config == null ? void 0 : config.formatting) == null ? void 0 : _U.formatCompactCurrency) != null ? _V : formatters.formatCompactCurrency,
1584
+ formatDate: (_X = (_W = config == null ? void 0 : config.formatting) == null ? void 0 : _W.formatDate) != null ? _X : formatters.formatDate
1534
1585
  },
1535
1586
  search: mergeAggUiSearchConfig(config == null ? void 0 : config.search),
1536
1587
  trading: {
1537
- executionMode: (_X = (_W = config == null ? void 0 : config.trading) == null ? void 0 : _W.executionMode) != null ? _X : defaultAggUiConfig.trading.executionMode
1588
+ executionMode: (_Z = (_Y = config == null ? void 0 : config.trading) == null ? void 0 : _Y.executionMode) != null ? _Z : defaultAggUiConfig.trading.executionMode
1538
1589
  },
1539
1590
  walletActions: config == null ? void 0 : config.walletActions,
1540
1591
  solanaRpcUrl: config == null ? void 0 : config.solanaRpcUrl
@@ -2519,6 +2570,98 @@ var applyOrderbookDepth = (data, depth) => {
2519
2570
  });
2520
2571
  };
2521
2572
 
2573
+ // src/market-data/market-resolution-cache.ts
2574
+ var isRecord = (value) => {
2575
+ return typeof value === "object" && value !== null;
2576
+ };
2577
+ var NESTED_COLLECTION_FIELDS = ["pages", "data", "markets", "events", "venueMarkets"];
2578
+ var marketContainsOutcomeId = (market, outcomeId) => {
2579
+ if (!isRecord(market)) return false;
2580
+ const outcomes = market.venueMarketOutcomes;
2581
+ if (!Array.isArray(outcomes)) return false;
2582
+ return outcomes.some((outcome) => isRecord(outcome) && outcome.id === outcomeId);
2583
+ };
2584
+ var cachedDataContainsOutcomeId = (data, outcomeId) => {
2585
+ if (Array.isArray(data)) {
2586
+ return data.some((entry) => cachedDataContainsOutcomeId(entry, outcomeId));
2587
+ }
2588
+ if (!isRecord(data)) return false;
2589
+ if (marketContainsOutcomeId(data, outcomeId)) return true;
2590
+ return NESTED_COLLECTION_FIELDS.some((field) => {
2591
+ const value = data[field];
2592
+ return Array.isArray(value) && value.some((entry) => cachedDataContainsOutcomeId(entry, outcomeId));
2593
+ });
2594
+ };
2595
+ var normalizeLabel = (label) => {
2596
+ return typeof label === "string" ? label.trim().toLowerCase() : "";
2597
+ };
2598
+ var findResolvedOutcome = (resolvedOutcomes, outcome) => {
2599
+ var _a;
2600
+ const externalIdentifier = outcome.externalIdentifier;
2601
+ if (typeof externalIdentifier === "string" && externalIdentifier.length > 0) {
2602
+ const matchedByExternalId = resolvedOutcomes.find(
2603
+ (resolved) => resolved.externalIdentifier === externalIdentifier
2604
+ );
2605
+ if (matchedByExternalId) return matchedByExternalId;
2606
+ }
2607
+ const label = normalizeLabel(outcome.label);
2608
+ if (label) {
2609
+ return (_a = resolvedOutcomes.find((resolved) => normalizeLabel(resolved.label) === label)) != null ? _a : null;
2610
+ }
2611
+ return null;
2612
+ };
2613
+ var applyWinnersToOutcomes = (outcomes, resolution) => {
2614
+ let changed = false;
2615
+ const next = outcomes.map((outcome) => {
2616
+ if (!isRecord(outcome)) return outcome;
2617
+ const resolved = findResolvedOutcome(resolution.outcomes, outcome);
2618
+ if (!resolved) return outcome;
2619
+ const nextWinner = resolved.winner === true;
2620
+ if (outcome.winner === nextWinner) return outcome;
2621
+ changed = true;
2622
+ return __spreadProps(__spreadValues({}, outcome), { winner: nextWinner });
2623
+ });
2624
+ return changed ? next : outcomes;
2625
+ };
2626
+ var applyResolutionToMarket = (market, resolution) => {
2627
+ const outcomes = market.venueMarketOutcomes;
2628
+ if (!Array.isArray(outcomes)) return market;
2629
+ if (!outcomes.some((outcome) => isRecord(outcome) && outcome.id === resolution.outcomeId)) {
2630
+ return market;
2631
+ }
2632
+ const nextOutcomes = applyWinnersToOutcomes(outcomes, resolution);
2633
+ const statusChanged = market.status !== resolution.status;
2634
+ if (!statusChanged && nextOutcomes === outcomes) return market;
2635
+ return __spreadProps(__spreadValues({}, market), { status: resolution.status, venueMarketOutcomes: nextOutcomes });
2636
+ };
2637
+ var applyResolutionToCachedData = (data, resolution) => {
2638
+ if (Array.isArray(data)) {
2639
+ let changed2 = false;
2640
+ const next2 = data.map((entry) => {
2641
+ const updated = applyResolutionToCachedData(entry, resolution);
2642
+ if (updated !== entry) changed2 = true;
2643
+ return updated;
2644
+ });
2645
+ return changed2 ? next2 : data;
2646
+ }
2647
+ if (!isRecord(data)) return data;
2648
+ if (Array.isArray(data.venueMarketOutcomes)) {
2649
+ return applyResolutionToMarket(data, resolution);
2650
+ }
2651
+ let changed = false;
2652
+ const next = __spreadValues({}, data);
2653
+ for (const field of NESTED_COLLECTION_FIELDS) {
2654
+ const value = data[field];
2655
+ if (!Array.isArray(value)) continue;
2656
+ const updated = applyResolutionToCachedData(value, resolution);
2657
+ if (updated !== value) {
2658
+ next[field] = updated;
2659
+ changed = true;
2660
+ }
2661
+ }
2662
+ return changed ? next : data;
2663
+ };
2664
+
2522
2665
  // src/market-data/query-keys.ts
2523
2666
  var marketDataKeys = {
2524
2667
  all: () => ["market-data"],
@@ -2786,6 +2929,62 @@ function AggWebSocketProvider({ children }) {
2786
2929
  const invalidateActivityCaches = (0, import_react6.useCallback)(() => {
2787
2930
  invalidateUserActivityQueries(queryClient);
2788
2931
  }, [queryClient]);
2932
+ const invalidateResolutionCaches = (0, import_react6.useCallback)(
2933
+ (resolution) => {
2934
+ const { outcomeId } = resolution;
2935
+ syncLiveQuery(outcomeId, (previous) => {
2936
+ if (!previous) return previous;
2937
+ if (previous.orderbook == null && previous.orderbookError == null) return previous;
2938
+ return __spreadProps(__spreadValues({}, previous), {
2939
+ orderbook: null,
2940
+ orderbookError: null,
2941
+ integrity: "ok"
2942
+ });
2943
+ });
2944
+ const affectedQueries = queryClient.getQueryCache().findAll({
2945
+ predicate: (query) => cachedDataContainsOutcomeId(query.state.data, outcomeId)
2946
+ });
2947
+ for (const query of affectedQueries) {
2948
+ queryClient.setQueryData(
2949
+ query.queryKey,
2950
+ (previous) => applyResolutionToCachedData(previous, resolution)
2951
+ );
2952
+ }
2953
+ queryClient.invalidateQueries({
2954
+ queryKey: ["midpoints"],
2955
+ refetchType: "all"
2956
+ });
2957
+ queryClient.invalidateQueries({
2958
+ queryKey: ["venue-market-midpoints"],
2959
+ refetchType: "all"
2960
+ });
2961
+ queryClient.invalidateQueries({
2962
+ queryKey: ["venue-event"],
2963
+ refetchType: "all"
2964
+ });
2965
+ queryClient.invalidateQueries({
2966
+ queryKey: ["venue-markets"],
2967
+ refetchType: "all"
2968
+ });
2969
+ queryClient.invalidateQueries({
2970
+ queryKey: ["events"],
2971
+ refetchType: "all"
2972
+ });
2973
+ queryClient.invalidateQueries({
2974
+ queryKey: ["event-list"],
2975
+ refetchType: "all"
2976
+ });
2977
+ queryClient.invalidateQueries({
2978
+ queryKey: ["search"],
2979
+ refetchType: "all"
2980
+ });
2981
+ queryClient.invalidateQueries({
2982
+ predicate: (query) => cachedDataContainsOutcomeId(query.state.data, outcomeId),
2983
+ refetchType: "all"
2984
+ });
2985
+ },
2986
+ [queryClient, syncLiveQuery]
2987
+ );
2789
2988
  const callbacks = (0, import_react6.useMemo)(
2790
2989
  () => ({
2791
2990
  onSnapshot: (marketId, book) => {
@@ -2934,6 +3133,14 @@ function AggWebSocketProvider({ children }) {
2934
3133
  listener(msg);
2935
3134
  }
2936
3135
  },
3136
+ onMarketResolved: (msg) => {
3137
+ invalidateResolutionCaches(msg);
3138
+ if (isClientAuthenticated) {
3139
+ invalidateBalanceCaches();
3140
+ invalidatePositionCaches();
3141
+ invalidateActivityCaches();
3142
+ }
3143
+ },
2937
3144
  onError: (msg) => {
2938
3145
  const outcomeId = resolveSnapshotUnavailableOutcomeId(msg.message);
2939
3146
  if (!outcomeId) return;
@@ -2971,6 +3178,7 @@ function AggWebSocketProvider({ children }) {
2971
3178
  invalidateActivityCaches,
2972
3179
  invalidateBalanceCaches,
2973
3180
  invalidatePositionCaches,
3181
+ invalidateResolutionCaches,
2974
3182
  isClientAuthenticated,
2975
3183
  queryClient,
2976
3184
  syncChartQueries,
@@ -3894,6 +4102,7 @@ function mapOrderStatusToTerminalEvent(status) {
3894
4102
  }
3895
4103
  function useExecutionProgress({
3896
4104
  orderIds,
4105
+ quoteId,
3897
4106
  enabled,
3898
4107
  mode
3899
4108
  }) {
@@ -4069,17 +4278,202 @@ function useExecutionProgress({
4069
4278
  return;
4070
4279
  }
4071
4280
  }, []);
4072
- const isListening = enabled && !!orderIds && orderIds.length > 0;
4281
+ const isStatusPolling = enabled && !!quoteId;
4282
+ const isListening = !isStatusPolling && enabled && !!orderIds && orderIds.length > 0;
4073
4283
  useOnOrderSubmitted(isListening ? handleOrderSubmitted : null);
4074
4284
  useOnBalanceUpdate(isListening ? handleBalanceUpdate : null);
4075
4285
  useOnOrderEvent(isListening ? handleOrderEvent : null);
4076
4286
  const client = useAggClient();
4077
4287
  const terminalOrderIdsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
4078
4288
  const pollInFlightRef = (0, import_react10.useRef)(false);
4289
+ const buildSubmittedOrdersFromStatus = (0, import_react10.useCallback)(
4290
+ (orders) => {
4291
+ return orders.map((order) => {
4292
+ var _a, _b;
4293
+ return {
4294
+ type: "order_submitted",
4295
+ venue: order.venue,
4296
+ orderId: order.orderId,
4297
+ side: "",
4298
+ price: Number((_b = (_a = order.executionPriceRaw) != null ? _a : order.quotedPriceRaw) != null ? _b : 0),
4299
+ size: 0,
4300
+ timestamp: new Date(order.updatedAt).getTime() / 1e3
4301
+ };
4302
+ });
4303
+ },
4304
+ []
4305
+ );
4306
+ const buildTerminalEventsFromStatus = (0, import_react10.useCallback)(
4307
+ (status, fallbackOrderIds, fallbackTimestamp) => {
4308
+ const terminalEvents = status.orders.map((order) => {
4309
+ var _a, _b;
4310
+ const mappedEvent = (_a = order.event) != null ? _a : mapOrderStatusToTerminalEvent(order.status);
4311
+ if (!mappedEvent) return null;
4312
+ return {
4313
+ orderId: order.orderId,
4314
+ venue: order.venue,
4315
+ event: mappedEvent,
4316
+ filledAmountRaw: order.filledAmountRaw,
4317
+ remainingAmountRaw: order.remainingAmountRaw,
4318
+ actualSharesRaw: order.actualSharesRaw,
4319
+ actualToWinRaw: order.actualToWinRaw,
4320
+ quotedSharesRaw: order.quotedSharesRaw,
4321
+ quotedToWinRaw: order.quotedToWinRaw,
4322
+ executionPriceRaw: order.executionPriceRaw,
4323
+ quotedPriceRaw: order.quotedPriceRaw,
4324
+ errorReason: (_b = order.errorReason) != null ? _b : order.partialFillReason,
4325
+ timestamp: new Date(order.updatedAt).getTime() || fallbackTimestamp
4326
+ };
4327
+ }).filter((order) => order != null);
4328
+ if (!status.terminal || terminalEvents.length > 0 || !["failed", "cancelled", "expired"].includes(status.overallState)) {
4329
+ return terminalEvents;
4330
+ }
4331
+ return fallbackOrderIds.map((orderId) => {
4332
+ var _a;
4333
+ return {
4334
+ orderId,
4335
+ venue: "",
4336
+ event: "failed",
4337
+ errorReason: (_a = status.errorReason) != null ? _a : "Execution failed.",
4338
+ timestamp: fallbackTimestamp
4339
+ };
4340
+ });
4341
+ },
4342
+ []
4343
+ );
4344
+ const setFatalPollingFailure = (0, import_react10.useCallback)((message, failedOrderIds) => {
4345
+ setDagProgress((prev) => {
4346
+ var _a, _b, _c, _d, _e, _f;
4347
+ return {
4348
+ dagRunId: (_a = prev == null ? void 0 : prev.dagRunId) != null ? _a : "",
4349
+ totalSteps: (_b = prev == null ? void 0 : prev.totalSteps) != null ? _b : 0,
4350
+ currentSequence: (_c = prev == null ? void 0 : prev.currentSequence) != null ? _c : 0,
4351
+ currentStepType: (_d = prev == null ? void 0 : prev.currentStepType) != null ? _d : null,
4352
+ completedSequences: (_e = prev == null ? void 0 : prev.completedSequences) != null ? _e : [],
4353
+ stepTypes: (_f = prev == null ? void 0 : prev.stepTypes) != null ? _f : {},
4354
+ status: "failed",
4355
+ errorReason: message
4356
+ };
4357
+ });
4358
+ setTerminalOrderEvents((prev) => {
4359
+ const existingByOrderId = new Map(prev.map((event) => [event.orderId, event]));
4360
+ const timestamp = Date.now();
4361
+ for (const orderId of failedOrderIds) {
4362
+ if (existingByOrderId.has(orderId)) continue;
4363
+ existingByOrderId.set(orderId, {
4364
+ orderId,
4365
+ venue: "",
4366
+ event: "failed",
4367
+ errorReason: message,
4368
+ timestamp
4369
+ });
4370
+ }
4371
+ return Array.from(existingByOrderId.values()).sort(
4372
+ (left, right) => left.timestamp - right.timestamp
4373
+ );
4374
+ });
4375
+ }, []);
4079
4376
  (0, import_react10.useEffect)(() => {
4080
4377
  terminalOrderIdsRef.current = new Set(terminalOrderEvents.map((e) => e.orderId));
4081
4378
  }, [terminalOrderEvents]);
4082
4379
  (0, import_react10.useEffect)(() => {
4380
+ if (!isStatusPolling || !quoteId) return;
4381
+ let cancelled = false;
4382
+ let timeout = null;
4383
+ const stopPolling = () => {
4384
+ if (timeout !== null) {
4385
+ clearTimeout(timeout);
4386
+ timeout = null;
4387
+ }
4388
+ };
4389
+ const scheduleNextPoll = (delayMs) => {
4390
+ if (cancelled) return;
4391
+ timeout = setTimeout(() => {
4392
+ void pollExecutionStatus();
4393
+ }, delayMs != null ? delayMs : ORDER_POLL_INTERVAL_MS);
4394
+ };
4395
+ const pollExecutionStatus = () => __async(null, null, function* () {
4396
+ if (cancelled || pollInFlightRef.current) return;
4397
+ pollInFlightRef.current = true;
4398
+ try {
4399
+ const status = yield client.getExecutionStatus(__spreadValues({
4400
+ quoteId
4401
+ }, mode ? { mode } : {}));
4402
+ if (cancelled) return;
4403
+ const resolvedOrderIds = status.orderIds.length > 0 ? status.orderIds : orderIds != null ? orderIds : [];
4404
+ if (resolvedOrderIds.length > 0) {
4405
+ setPhase("order_submitted");
4406
+ }
4407
+ setSubmittedOrders(buildSubmittedOrdersFromStatus(status.orders));
4408
+ if (status.dagProgress) {
4409
+ setDagProgress(__spreadProps(__spreadValues({}, status.dagProgress), {
4410
+ stepTypes: Object.fromEntries(
4411
+ Object.entries(status.dagProgress.stepTypes).map(([sequence, stepType]) => [
4412
+ Number(sequence),
4413
+ stepType
4414
+ ])
4415
+ )
4416
+ }));
4417
+ } else if (status.terminal && ["failed", "cancelled", "expired"].includes(status.overallState)) {
4418
+ setDagProgress((prev) => {
4419
+ var _a, _b, _c, _d, _e, _f, _g;
4420
+ return {
4421
+ dagRunId: (_b = (_a = prev == null ? void 0 : prev.dagRunId) != null ? _a : status.executionId) != null ? _b : "",
4422
+ totalSteps: (_c = prev == null ? void 0 : prev.totalSteps) != null ? _c : status.steps.length,
4423
+ currentSequence: (_d = prev == null ? void 0 : prev.currentSequence) != null ? _d : 0,
4424
+ currentStepType: (_e = prev == null ? void 0 : prev.currentStepType) != null ? _e : null,
4425
+ completedSequences: (_f = prev == null ? void 0 : prev.completedSequences) != null ? _f : [],
4426
+ stepTypes: (_g = prev == null ? void 0 : prev.stepTypes) != null ? _g : {},
4427
+ status: "failed",
4428
+ errorReason: status.errorReason
4429
+ };
4430
+ });
4431
+ }
4432
+ const fallbackTimestamp = Date.now();
4433
+ const nextTerminalEvents = buildTerminalEventsFromStatus(
4434
+ status,
4435
+ resolvedOrderIds,
4436
+ fallbackTimestamp
4437
+ );
4438
+ setTerminalOrderEvents(nextTerminalEvents);
4439
+ if (status.terminal) {
4440
+ stopPolling();
4441
+ return;
4442
+ }
4443
+ scheduleNextPoll(status.pollAfterMs);
4444
+ } catch (error) {
4445
+ if (cancelled) return;
4446
+ const statusCode = typeof error === "object" && error != null && "status" in error && typeof error.status === "number" ? error.status : null;
4447
+ if (statusCode === 400 || statusCode === 401 || statusCode === 403) {
4448
+ setFatalPollingFailure(
4449
+ error instanceof Error ? error.message : "Execution status polling failed.",
4450
+ orderIds != null ? orderIds : []
4451
+ );
4452
+ stopPolling();
4453
+ return;
4454
+ }
4455
+ scheduleNextPoll(ORDER_POLL_INTERVAL_MS);
4456
+ } finally {
4457
+ pollInFlightRef.current = false;
4458
+ }
4459
+ });
4460
+ void pollExecutionStatus();
4461
+ return () => {
4462
+ cancelled = true;
4463
+ stopPolling();
4464
+ };
4465
+ }, [
4466
+ buildSubmittedOrdersFromStatus,
4467
+ buildTerminalEventsFromStatus,
4468
+ client,
4469
+ isStatusPolling,
4470
+ mode,
4471
+ orderIds,
4472
+ quoteId,
4473
+ setFatalPollingFailure
4474
+ ]);
4475
+ (0, import_react10.useEffect)(() => {
4476
+ if (isStatusPolling) return;
4083
4477
  if (!isListening || !(orderIds == null ? void 0 : orderIds.length)) return;
4084
4478
  let cancelled = false;
4085
4479
  let interval = null;
@@ -4167,7 +4561,7 @@ function useExecutionProgress({
4167
4561
  cancelled = true;
4168
4562
  stopPolling();
4169
4563
  };
4170
- }, [client, isListening, mode, orderIds]);
4564
+ }, [client, isListening, isStatusPolling, mode, orderIds]);
4171
4565
  return { phase, submittedOrders, latestBalance, dagProgress, terminalOrderEvents };
4172
4566
  }
4173
4567
 
@@ -5806,6 +6200,7 @@ function findLivePriceById(livePrices, id) {
5806
6200
  var import_react27 = require("react");
5807
6201
  var import_react_query25 = require("@tanstack/react-query");
5808
6202
  var EMPTY = /* @__PURE__ */ new Map();
6203
+ var EMPTY_CANDIDATES = /* @__PURE__ */ new Map();
5809
6204
  var extractOutcomeBestPrices = (state) => {
5810
6205
  var _a, _b;
5811
6206
  const ob = state == null ? void 0 : state.orderbook;
@@ -5923,6 +6318,175 @@ function mergeBestPricesPreferringLive(rest, live) {
5923
6318
  }
5924
6319
  return merged;
5925
6320
  }
6321
+ var pickSideVenue = (venues, level, side) => {
6322
+ if (venues) {
6323
+ let bestVenue;
6324
+ let bestValue;
6325
+ for (const [venue, info] of Object.entries(venues)) {
6326
+ const value = side === "bid" ? info.bestBid : info.bestAsk;
6327
+ if (value == null) continue;
6328
+ const wins = bestValue == null || (side === "bid" ? value > bestValue : value < bestValue);
6329
+ if (wins) {
6330
+ bestValue = value;
6331
+ bestVenue = venue;
6332
+ }
6333
+ }
6334
+ if (bestVenue != null) return bestVenue;
6335
+ }
6336
+ if (level == null ? void 0 : level.venues) {
6337
+ let bestVenue;
6338
+ let bestSize = -Infinity;
6339
+ for (const [venue, size] of Object.entries(level.venues)) {
6340
+ if (size > bestSize) {
6341
+ bestSize = size;
6342
+ bestVenue = venue;
6343
+ }
6344
+ }
6345
+ if (bestVenue != null) return bestVenue;
6346
+ }
6347
+ return void 0;
6348
+ };
6349
+ var extractOutcomeBestCandidate = (state) => {
6350
+ var _a;
6351
+ const ob = state == null ? void 0 : state.orderbook;
6352
+ if (!ob) return {};
6353
+ const candidate = {};
6354
+ const bidLevel = ob.bids[0];
6355
+ const askLevel = ob.asks[0];
6356
+ if ((bidLevel == null ? void 0 : bidLevel.price) != null) {
6357
+ candidate.bestBid = bidLevel.price;
6358
+ const venue = pickSideVenue(ob.venues, bidLevel, "bid");
6359
+ if (venue) candidate.bestBidVenue = venue;
6360
+ }
6361
+ if ((askLevel == null ? void 0 : askLevel.price) != null) {
6362
+ candidate.bestAsk = askLevel.price;
6363
+ const venue = pickSideVenue(ob.venues, askLevel, "ask");
6364
+ if (venue) candidate.bestAskVenue = venue;
6365
+ }
6366
+ if (ob.midpoint != null) {
6367
+ candidate.midpoint = ob.midpoint;
6368
+ const midVenue = (_a = candidate.bestAskVenue) != null ? _a : candidate.bestBidVenue;
6369
+ if (midVenue) candidate.midpointVenue = midVenue;
6370
+ }
6371
+ if (ob.timestamp != null) candidate.updatedAt = ob.timestamp;
6372
+ return candidate;
6373
+ };
6374
+ function buildLiveBestPriceCandidates(outcomeIds, states, venueMarkets) {
6375
+ var _a, _b, _c;
6376
+ const perOutcome = /* @__PURE__ */ new Map();
6377
+ for (let i = 0; i < outcomeIds.length; i++) {
6378
+ const candidate = extractOutcomeBestCandidate(states[i]);
6379
+ if (candidate.bestBid != null || candidate.bestAsk != null || candidate.midpoint != null) {
6380
+ perOutcome.set(outcomeIds[i], candidate);
6381
+ }
6382
+ }
6383
+ if (perOutcome.size === 0 || !(venueMarkets == null ? void 0 : venueMarkets.length)) {
6384
+ return perOutcome;
6385
+ }
6386
+ const result = new Map(perOutcome);
6387
+ for (const vm of venueMarkets) {
6388
+ for (const outcome of (_a = vm.venueMarketOutcomes) != null ? _a : []) {
6389
+ const refs = (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : [];
6390
+ if (!refs.length) continue;
6391
+ const group = [outcome.id, ...refs.map((ref) => ref.venueMarketOutcomeId)];
6392
+ let groupBestAsk;
6393
+ let groupBestAskVenue;
6394
+ let groupBestBid;
6395
+ let groupBestBidVenue;
6396
+ let groupUpdatedAt;
6397
+ for (const id of group) {
6398
+ const entry = perOutcome.get(id);
6399
+ if (!entry) continue;
6400
+ if (entry.bestAsk != null && (groupBestAsk == null || entry.bestAsk < groupBestAsk)) {
6401
+ groupBestAsk = entry.bestAsk;
6402
+ groupBestAskVenue = entry.bestAskVenue;
6403
+ }
6404
+ if (entry.bestBid != null && (groupBestBid == null || entry.bestBid > groupBestBid)) {
6405
+ groupBestBid = entry.bestBid;
6406
+ groupBestBidVenue = entry.bestBidVenue;
6407
+ }
6408
+ if (entry.updatedAt != null && (groupUpdatedAt == null || entry.updatedAt > groupUpdatedAt)) {
6409
+ groupUpdatedAt = entry.updatedAt;
6410
+ }
6411
+ }
6412
+ if (groupBestAsk == null && groupBestBid == null) continue;
6413
+ for (const id of group) {
6414
+ const prev = (_c = result.get(id)) != null ? _c : {};
6415
+ const next = __spreadValues({}, prev);
6416
+ if (groupBestBid != null) {
6417
+ next.bestBid = groupBestBid;
6418
+ if (groupBestBidVenue) next.bestBidVenue = groupBestBidVenue;
6419
+ }
6420
+ if (groupBestAsk != null) {
6421
+ next.bestAsk = groupBestAsk;
6422
+ if (groupBestAskVenue) next.bestAskVenue = groupBestAskVenue;
6423
+ }
6424
+ if (groupUpdatedAt != null) next.updatedAt = groupUpdatedAt;
6425
+ result.set(id, next);
6426
+ }
6427
+ }
6428
+ }
6429
+ return result;
6430
+ }
6431
+ var buildCandidateFingerprint = (outcomeIds, queries) => {
6432
+ var _a, _b, _c, _d;
6433
+ const parts = [];
6434
+ for (let i = 0; i < outcomeIds.length; i++) {
6435
+ const ob = (_b = (_a = queries[i]) == null ? void 0 : _a.data) == null ? void 0 : _b.orderbook;
6436
+ const bid = (_c = ob == null ? void 0 : ob.bids[0]) == null ? void 0 : _c.price;
6437
+ const ask = (_d = ob == null ? void 0 : ob.asks[0]) == null ? void 0 : _d.price;
6438
+ const mid = ob == null ? void 0 : ob.midpoint;
6439
+ const ts = ob == null ? void 0 : ob.timestamp;
6440
+ const venues = (ob == null ? void 0 : ob.venues) ? Object.keys(ob.venues).sort().join(",") : "";
6441
+ parts.push(`${outcomeIds[i]}:${bid != null ? bid : "_"}:${ask != null ? ask : "_"}:${mid != null ? mid : "_"}:${ts != null ? ts : "_"}:${venues}`);
6442
+ }
6443
+ return parts.join("|");
6444
+ };
6445
+ function useLiveBestPriceCandidates(venueMarkets) {
6446
+ const {
6447
+ features: { enableLiveUpdates }
6448
+ } = useAggUiConfig();
6449
+ const outcomeIds = (0, import_react27.useMemo)(() => {
6450
+ var _a, _b;
6451
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
6452
+ const ids = /* @__PURE__ */ new Set();
6453
+ for (const vm of venueMarkets) {
6454
+ for (const outcome of (_a = vm.venueMarketOutcomes) != null ? _a : []) {
6455
+ if (outcome.id) ids.add(outcome.id);
6456
+ for (const ref of (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : []) {
6457
+ if (ref.venueMarketOutcomeId) ids.add(ref.venueMarketOutcomeId);
6458
+ }
6459
+ }
6460
+ }
6461
+ return [...ids].sort();
6462
+ }, [venueMarkets]);
6463
+ const queries = (0, import_react_query25.useQueries)({
6464
+ queries: outcomeIds.map((id) => ({
6465
+ queryKey: marketDataKeys.live(id),
6466
+ queryFn: () => createMarketLiveState(id),
6467
+ enabled: false,
6468
+ staleTime: Infinity,
6469
+ gcTime: 5 * 6e4,
6470
+ initialData: () => createMarketLiveState(id)
6471
+ }))
6472
+ });
6473
+ const fingerprint = buildCandidateFingerprint(outcomeIds, queries);
6474
+ const prevRef = (0, import_react27.useRef)({
6475
+ fingerprint: "",
6476
+ result: EMPTY_CANDIDATES
6477
+ });
6478
+ return (0, import_react27.useMemo)(() => {
6479
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length) || !enableLiveUpdates) return EMPTY_CANDIDATES;
6480
+ if (fingerprint === prevRef.current.fingerprint) return prevRef.current.result;
6481
+ const states = outcomeIds.map((_, i) => {
6482
+ var _a;
6483
+ return (_a = queries[i]) == null ? void 0 : _a.data;
6484
+ });
6485
+ const result = buildLiveBestPriceCandidates(outcomeIds, states, venueMarkets);
6486
+ prevRef.current = { fingerprint, result };
6487
+ return result;
6488
+ }, [venueMarkets, enableLiveUpdates, fingerprint, outcomeIds, queries]);
6489
+ }
5926
6490
 
5927
6491
  // src/use-live-trades.ts
5928
6492
  function useLiveTrades(canonicalMarketId) {
@@ -6167,31 +6731,8 @@ function useMidpoints(venueMarkets, options) {
6167
6731
  };
6168
6732
  }
6169
6733
 
6170
- // src/use-tradable-venues.ts
6171
- var import_react29 = require("react");
6172
- function useTradableVenues(venueMarkets) {
6173
- const { prices, isLoading } = useMidpoints(venueMarkets);
6174
- const tradableVenues = (0, import_react29.useMemo)(() => {
6175
- var _a;
6176
- if (isLoading) return null;
6177
- if (!venueMarkets || venueMarkets.length === 0) return /* @__PURE__ */ new Set();
6178
- const set = /* @__PURE__ */ new Set();
6179
- for (const market of venueMarkets) {
6180
- const outcomes = (_a = market.venueMarketOutcomes) != null ? _a : [];
6181
- for (const outcome of outcomes) {
6182
- if (prices.has(outcome.id)) {
6183
- set.add(market.venue);
6184
- break;
6185
- }
6186
- }
6187
- }
6188
- return set;
6189
- }, [venueMarkets, prices, isLoading]);
6190
- return { tradableVenues, isLoading };
6191
- }
6192
-
6193
6734
  // src/use-rolling-chart-window.ts
6194
- var import_react30 = require("react");
6735
+ var import_react29 = require("react");
6195
6736
  var RANGE_SECONDS_BY_RANGE = {
6196
6737
  "1H": 60 * 60,
6197
6738
  "6H": 6 * 60 * 60,
@@ -6222,16 +6763,16 @@ var useRollingChartWindow = (options) => {
6222
6763
  var _a;
6223
6764
  const tickMs = (_a = options.tickMs) != null ? _a : 1e3;
6224
6765
  const optionsNowMs = options.nowMs;
6225
- const nowMs = (0, import_react30.useMemo)(() => optionsNowMs != null ? optionsNowMs : (() => Date.now()), [optionsNowMs]);
6226
- const [nowSec, setNowSec] = (0, import_react30.useState)(() => Math.floor(nowMs() / 1e3));
6227
- (0, import_react30.useEffect)(() => {
6766
+ const nowMs = (0, import_react29.useMemo)(() => optionsNowMs != null ? optionsNowMs : (() => Date.now()), [optionsNowMs]);
6767
+ const [nowSec, setNowSec] = (0, import_react29.useState)(() => Math.floor(nowMs() / 1e3));
6768
+ (0, import_react29.useEffect)(() => {
6228
6769
  setNowSec(Math.floor(nowMs() / 1e3));
6229
6770
  const handle = setInterval(() => {
6230
6771
  setNowSec(Math.floor(nowMs() / 1e3));
6231
6772
  }, tickMs);
6232
6773
  return () => clearInterval(handle);
6233
6774
  }, [tickMs, nowMs]);
6234
- return (0, import_react30.useMemo)(
6775
+ return (0, import_react29.useMemo)(
6235
6776
  () => resolveRollingWindow({ range: options.range, nowSec, interval: options.interval }),
6236
6777
  [options.range, options.interval, nowSec]
6237
6778
  );
@@ -6324,11 +6865,11 @@ function useMarketOrderbook(options) {
6324
6865
  }
6325
6866
 
6326
6867
  // src/use-arb.ts
6327
- var import_react31 = require("react");
6868
+ var import_react30 = require("react");
6328
6869
  function useMarketArb(marketId) {
6329
6870
  const ws = useAggWebSocket();
6330
- const [state, setState] = (0, import_react31.useState)({ arbReturn: null, isLive: false });
6331
- (0, import_react31.useEffect)(() => {
6871
+ const [state, setState] = (0, import_react30.useState)({ arbReturn: null, isLive: false });
6872
+ (0, import_react30.useEffect)(() => {
6332
6873
  if (!ws || !marketId) return;
6333
6874
  const cached = ws.getArb(marketId);
6334
6875
  if (cached != null) {
@@ -6347,10 +6888,10 @@ var EMPTY_ARB_FEED = {
6347
6888
  };
6348
6889
  function useArbFeed() {
6349
6890
  const ws = useAggWebSocket();
6350
- const [state, setState] = (0, import_react31.useState)(EMPTY_ARB_FEED);
6351
- const stateRef = (0, import_react31.useRef)(state);
6891
+ const [state, setState] = (0, import_react30.useState)(EMPTY_ARB_FEED);
6892
+ const stateRef = (0, import_react30.useRef)(state);
6352
6893
  stateRef.current = state;
6353
- (0, import_react31.useEffect)(() => {
6894
+ (0, import_react30.useEffect)(() => {
6354
6895
  if (!ws) return;
6355
6896
  const off = ws.subscribeArbFeed((batch) => {
6356
6897
  setState((prev) => {
@@ -6590,15 +7131,15 @@ function useOrders(options = {}) {
6590
7131
 
6591
7132
  // src/use-search.ts
6592
7133
  var import_react_query31 = require("@tanstack/react-query");
6593
- var import_react32 = require("react");
7134
+ var import_react31 = require("react");
6594
7135
  function useSearch(options) {
6595
7136
  var _a, _b, _c;
6596
- const client = (0, import_react32.useContext)(AggClientContext);
6597
- const queryClient = (0, import_react32.useContext)(import_react_query31.QueryClientContext);
6598
- const [fallbackQueryClient] = (0, import_react32.useState)(() => new import_react_query31.QueryClient());
7137
+ const client = (0, import_react31.useContext)(AggClientContext);
7138
+ const queryClient = (0, import_react31.useContext)(import_react_query31.QueryClientContext);
7139
+ const [fallbackQueryClient] = (0, import_react31.useState)(() => new import_react_query31.QueryClient());
6599
7140
  const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
6600
7141
  const isEnabled = enabled && q.length > 0;
6601
- (0, import_react32.useEffect)(() => {
7142
+ (0, import_react31.useEffect)(() => {
6602
7143
  if (queryClient) return void 0;
6603
7144
  fallbackQueryClient.mount();
6604
7145
  return () => {
@@ -6652,7 +7193,7 @@ function useSearch(options) {
6652
7193
  }
6653
7194
 
6654
7195
  // src/use-market-search.ts
6655
- var import_react33 = require("react");
7196
+ var import_react32 = require("react");
6656
7197
  function useMarketSearch(options) {
6657
7198
  var _a;
6658
7199
  const {
@@ -6663,8 +7204,8 @@ function useMarketSearch(options) {
6663
7204
  enableSuggestions = true,
6664
7205
  minLength = 1
6665
7206
  } = options;
6666
- const [query, setQueryState] = (0, import_react33.useState)("");
6667
- const [submittedQuery, setSubmittedQuery] = (0, import_react33.useState)(null);
7207
+ const [query, setQueryState] = (0, import_react32.useState)("");
7208
+ const [submittedQuery, setSubmittedQuery] = (0, import_react32.useState)(null);
6668
7209
  const debouncedQuery = useDebouncedValue(query, debounceMs);
6669
7210
  const trimmedDebounced = debouncedQuery.trim();
6670
7211
  const suggestionsEnabled = enableSuggestions && trimmedDebounced.length >= minLength;
@@ -6685,10 +7226,10 @@ function useMarketSearch(options) {
6685
7226
  enabled: submittedQ.length > 0,
6686
7227
  deep: true
6687
7228
  });
6688
- const setQuery = (0, import_react33.useCallback)((value) => {
7229
+ const setQuery = (0, import_react32.useCallback)((value) => {
6689
7230
  setQueryState(value);
6690
7231
  }, []);
6691
- const submit = (0, import_react33.useCallback)(
7232
+ const submit = (0, import_react32.useCallback)(
6692
7233
  (q) => {
6693
7234
  const target = (q != null ? q : query).trim();
6694
7235
  if (target.length === 0) return;
@@ -6696,7 +7237,7 @@ function useMarketSearch(options) {
6696
7237
  },
6697
7238
  [query]
6698
7239
  );
6699
- const clear = (0, import_react33.useCallback)(() => {
7240
+ const clear = (0, import_react32.useCallback)(() => {
6700
7241
  setQueryState("");
6701
7242
  setSubmittedQuery(null);
6702
7243
  }, []);
@@ -6739,7 +7280,130 @@ function useMarketSearch(options) {
6739
7280
 
6740
7281
  // src/use-smart-route.ts
6741
7282
  var import_react_query32 = require("@tanstack/react-query");
7283
+
7284
+ // src/smart-route-refresh-policy.ts
7285
+ var THIN_SMART_ROUTE_REFETCH_INTERVAL_MS = 5e3;
7286
+ var SMART_ROUTE_REFRESH_DEADLINE_BUFFER_MS = 4e3;
7287
+ var SMART_ROUTE_MIN_REFETCH_INTERVAL_MS = 5e3;
7288
+ var SMART_ROUTE_MAX_REFETCH_INTERVAL_MS = 2e4;
7289
+ var SMART_ROUTE_HIGH_SLIPPAGE_BPS = 75;
7290
+ var SMART_ROUTE_SHALLOW_TOP_LEVEL_RATIO = 0.7;
7291
+ var SMART_ROUTE_DEEP_FILL_LEVEL_COUNT = 3;
7292
+ var LIQUIDITY_CONSTRAINED_STATUSES = /* @__PURE__ */ new Set([
7293
+ "infeasible",
7294
+ "no_orderbooks",
7295
+ "insufficient_depth",
7296
+ "no_bids_above_min_price"
7297
+ ]);
7298
+ var THIN_LIQUIDITY_WARNING_PATTERN = /partial(?:[_\s-]?fill)?|insufficient(?:[_\s-]?liquidity|[_\s-]?depth)|shallow|price moved|no active quote path|couldn'?t fill|unable to fill|quote stale|stale/i;
7299
+ var resolveMsUntilIsoTimestamp = (value, nowMs) => {
7300
+ if (!value) return null;
7301
+ const parsedValue = Date.parse(value);
7302
+ if (!Number.isFinite(parsedValue)) return null;
7303
+ return parsedValue - nowMs;
7304
+ };
7305
+ var clampIntervalToRefreshDeadline = ({
7306
+ intervalMs,
7307
+ refreshAt,
7308
+ nowMs
7309
+ }) => {
7310
+ const msUntilRefresh = resolveMsUntilIsoTimestamp(refreshAt, nowMs);
7311
+ if (msUntilRefresh == null || msUntilRefresh <= 0) {
7312
+ return Math.min(
7313
+ SMART_ROUTE_MAX_REFETCH_INTERVAL_MS,
7314
+ Math.max(SMART_ROUTE_MIN_REFETCH_INTERVAL_MS, intervalMs)
7315
+ );
7316
+ }
7317
+ return Math.max(
7318
+ SMART_ROUTE_MIN_REFETCH_INTERVAL_MS,
7319
+ Math.min(SMART_ROUTE_MAX_REFETCH_INTERVAL_MS, intervalMs, Math.floor(msUntilRefresh))
7320
+ );
7321
+ };
7322
+ var assessThinSmartRouteLiquidity = (quote, nowMs = Date.now()) => {
7323
+ var _a, _b;
7324
+ if (!quote) {
7325
+ return {
7326
+ isThin: false,
7327
+ reasons: []
7328
+ };
7329
+ }
7330
+ const reasons = /* @__PURE__ */ new Set();
7331
+ if (LIQUIDITY_CONSTRAINED_STATUSES.has(quote.status)) {
7332
+ reasons.add("liquidity_status");
7333
+ }
7334
+ if (typeof ((_a = quote.slippage) == null ? void 0 : _a.slippageBps) === "number" && Number.isFinite(quote.slippage.slippageBps) && quote.slippage.slippageBps >= SMART_ROUTE_HIGH_SLIPPAGE_BPS) {
7335
+ reasons.add("high_slippage");
7336
+ }
7337
+ const msUntilRefresh = resolveMsUntilIsoTimestamp(quote.refreshAt, nowMs);
7338
+ if (msUntilRefresh != null && msUntilRefresh <= SMART_ROUTE_REFRESH_DEADLINE_BUFFER_MS) {
7339
+ reasons.add("refresh_due_soon");
7340
+ }
7341
+ const hasShallowTopLevel = quote.fills.some((fill) => {
7342
+ var _a2, _b2;
7343
+ if (fill.fills.length <= 1 || fill.venueQty <= 0) return false;
7344
+ const topLevelSize = (_b2 = (_a2 = fill.fills[0]) == null ? void 0 : _a2.size) != null ? _b2 : 0;
7345
+ if (!Number.isFinite(topLevelSize) || topLevelSize <= 0) return false;
7346
+ return topLevelSize / fill.venueQty < SMART_ROUTE_SHALLOW_TOP_LEVEL_RATIO;
7347
+ });
7348
+ if (hasShallowTopLevel) {
7349
+ reasons.add("shallow_top_level");
7350
+ }
7351
+ const hasDeepFillLevels = quote.fills.some(
7352
+ (fill) => fill.fills.length >= SMART_ROUTE_DEEP_FILL_LEVEL_COUNT
7353
+ );
7354
+ if (hasDeepFillLevels) {
7355
+ reasons.add("deep_fill_levels");
7356
+ }
7357
+ const hasThinWarning = ((_b = quote.warnings) != null ? _b : []).some(
7358
+ (warning) => THIN_LIQUIDITY_WARNING_PATTERN.test(warning.reason)
7359
+ );
7360
+ if (hasThinWarning) {
7361
+ reasons.add("warning_signal");
7362
+ }
7363
+ return {
7364
+ isThin: reasons.size > 0,
7365
+ reasons: [...reasons]
7366
+ };
7367
+ };
7368
+ var resolveSmartRouteRefetchInterval = (args, nowMs = Date.now()) => {
7369
+ const {
7370
+ aggressiveIntervalMs = THIN_SMART_ROUTE_REFETCH_INTERVAL_MS,
7371
+ data,
7372
+ defaultIntervalMs,
7373
+ isDocumentVisible,
7374
+ isEditing = false,
7375
+ isInputValid,
7376
+ isMarketOpen,
7377
+ isPanelActive,
7378
+ isSubmitting,
7379
+ queryEnabled
7380
+ } = args;
7381
+ if (defaultIntervalMs <= 0) return false;
7382
+ const isActivelyViewingQuote = isPanelActive || isEditing;
7383
+ if (!queryEnabled || !isInputValid || !isActivelyViewingQuote || !isMarketOpen || isSubmitting || !isDocumentVisible) {
7384
+ return false;
7385
+ }
7386
+ const defaultInterval = clampIntervalToRefreshDeadline({
7387
+ intervalMs: defaultIntervalMs,
7388
+ refreshAt: data == null ? void 0 : data.refreshAt,
7389
+ nowMs
7390
+ });
7391
+ if (!data) return defaultInterval;
7392
+ const thinLiquidity = assessThinSmartRouteLiquidity(data, nowMs);
7393
+ if (!thinLiquidity.isThin) return defaultInterval;
7394
+ return clampIntervalToRefreshDeadline({
7395
+ intervalMs: aggressiveIntervalMs,
7396
+ refreshAt: data.refreshAt,
7397
+ nowMs
7398
+ });
7399
+ };
7400
+
7401
+ // src/use-smart-route.ts
6742
7402
  var SMART_ROUTE_STALE_TIME_MS = 2e4;
7403
+ var getIsDocumentVisible = () => {
7404
+ if (typeof document === "undefined") return true;
7405
+ return document.visibilityState !== "hidden";
7406
+ };
6743
7407
  function useSmartRoute(options) {
6744
7408
  var _a, _b;
6745
7409
  const client = useAggClient();
@@ -6757,9 +7421,12 @@ function useSmartRoute(options) {
6757
7421
  compareVenues,
6758
7422
  deepEstimate,
6759
7423
  enabled = true,
6760
- staleTimeMs = SMART_ROUTE_STALE_TIME_MS
7424
+ staleTimeMs = SMART_ROUTE_STALE_TIME_MS,
7425
+ refreshContext
6761
7426
  } = options;
6762
7427
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
7428
+ const hasValidInput = (maxSpend != null ? maxSpend : 0) > 0 || (sellShares != null ? sellShares : 0) > 0;
7429
+ const queryEnabled = enabled && !!resolvedVenueMarketOutcomeId && hasValidInput;
6763
7430
  const query = (0, import_react_query32.useQuery)({
6764
7431
  queryKey: [
6765
7432
  "smart-route",
@@ -6791,11 +7458,25 @@ function useSmartRoute(options) {
6791
7458
  { signal }
6792
7459
  );
6793
7460
  }),
6794
- enabled: enabled && !!resolvedVenueMarketOutcomeId && ((maxSpend != null ? maxSpend : 0) > 0 || (sellShares != null ? sellShares : 0) > 0),
7461
+ enabled: queryEnabled,
6795
7462
  staleTime: staleTimeMs,
6796
- refetchInterval: staleTimeMs > 0 ? staleTimeMs : false,
7463
+ refetchInterval: (queryState) => {
7464
+ var _a2, _b2, _c, _d;
7465
+ return resolveSmartRouteRefetchInterval({
7466
+ data: queryState.state.data,
7467
+ defaultIntervalMs: staleTimeMs,
7468
+ isDocumentVisible: getIsDocumentVisible(),
7469
+ isEditing: (_a2 = refreshContext == null ? void 0 : refreshContext.isEditing) != null ? _a2 : false,
7470
+ isInputValid: hasValidInput,
7471
+ isMarketOpen: (_b2 = refreshContext == null ? void 0 : refreshContext.isMarketOpen) != null ? _b2 : true,
7472
+ isPanelActive: (_c = refreshContext == null ? void 0 : refreshContext.isPanelActive) != null ? _c : true,
7473
+ isSubmitting: (_d = refreshContext == null ? void 0 : refreshContext.isSubmitting) != null ? _d : false,
7474
+ queryEnabled
7475
+ });
7476
+ },
6797
7477
  gcTime: 6e4,
6798
7478
  refetchOnWindowFocus: false,
7479
+ refetchIntervalInBackground: false,
6799
7480
  retry: 1,
6800
7481
  placeholderData: import_react_query32.keepPreviousData
6801
7482
  });
@@ -6850,7 +7531,7 @@ function useUserHoldings(options) {
6850
7531
  }
6851
7532
 
6852
7533
  // src/use-enriched-venue-event.ts
6853
- var import_react35 = require("react");
7534
+ var import_react34 = require("react");
6854
7535
 
6855
7536
  // src/use-venue-event.ts
6856
7537
  var import_react_query34 = require("@tanstack/react-query");
@@ -6878,23 +7559,29 @@ function useVenueEvent(options) {
6878
7559
 
6879
7560
  // src/use-venue-markets.ts
6880
7561
  var import_react_query35 = require("@tanstack/react-query");
6881
- var import_react34 = require("react");
7562
+ var import_react33 = require("react");
6882
7563
  function useVenueMarkets(options) {
6883
- var _a, _b, _c, _d, _e;
6884
- const client = (0, import_react34.useContext)(AggClientContext);
6885
- const queryClient = (0, import_react34.useContext)(import_react_query35.QueryClientContext);
6886
- const [fallbackQueryClient] = (0, import_react34.useState)(() => new import_react_query35.QueryClient());
7564
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
7565
+ const client = (0, import_react33.useContext)(AggClientContext);
7566
+ const queryClient = (0, import_react33.useContext)(import_react_query35.QueryClientContext);
7567
+ const [fallbackQueryClient] = (0, import_react33.useState)(() => new import_react_query35.QueryClient());
6887
7568
  const venue = options == null ? void 0 : options.venue;
6888
7569
  const venueEventId = options == null ? void 0 : options.venueEventId;
6889
7570
  const search = options == null ? void 0 : options.search;
6890
7571
  const matchStatus = options == null ? void 0 : options.matchStatus;
6891
7572
  const status = options == null ? void 0 : options.status;
6892
7573
  const categoryIds = options == null ? void 0 : options.categoryIds;
7574
+ const aggKey = options == null ? void 0 : options.aggKey;
7575
+ const sportsMarketType = options == null ? void 0 : options.sportsMarketType;
7576
+ const period = options == null ? void 0 : options.period;
7577
+ const marketCategory = options == null ? void 0 : options.marketCategory;
7578
+ const marketGroup = options == null ? void 0 : options.marketGroup;
6893
7579
  const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
6894
7580
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
6895
7581
  const sortBy = options == null ? void 0 : options.sortBy;
6896
7582
  const sortDir = options == null ? void 0 : options.sortDir;
6897
- (0, import_react34.useEffect)(() => {
7583
+ const context = options == null ? void 0 : options.context;
7584
+ (0, import_react33.useEffect)(() => {
6898
7585
  if (queryClient) return void 0;
6899
7586
  fallbackQueryClient.mount();
6900
7587
  return () => {
@@ -6914,9 +7601,15 @@ function useVenueMarkets(options) {
6914
7601
  matchStatus != null ? matchStatus : "",
6915
7602
  status != null ? status : "",
6916
7603
  (_c = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _c : "",
7604
+ (_d = aggKey == null ? void 0 : aggKey.join(",")) != null ? _d : "",
7605
+ (_e = sportsMarketType == null ? void 0 : sportsMarketType.join(",")) != null ? _e : "",
7606
+ (_f = period == null ? void 0 : period.join(",")) != null ? _f : "",
7607
+ (_g = marketCategory == null ? void 0 : marketCategory.join(",")) != null ? _g : "",
7608
+ (_h = marketGroup == null ? void 0 : marketGroup.join(",")) != null ? _h : "",
6917
7609
  limit,
6918
7610
  sortBy != null ? sortBy : "",
6919
- sortDir != null ? sortDir : ""
7611
+ sortDir != null ? sortDir : "",
7612
+ context != null ? context : ""
6920
7613
  ],
6921
7614
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
6922
7615
  if (!client) {
@@ -6929,10 +7622,16 @@ function useVenueMarkets(options) {
6929
7622
  matchStatus,
6930
7623
  status,
6931
7624
  categoryIds,
7625
+ aggKey,
7626
+ sportsMarketType,
7627
+ period,
7628
+ marketCategory,
7629
+ marketGroup,
6932
7630
  limit,
6933
7631
  cursor: pageParam,
6934
7632
  sortBy,
6935
- sortDir
7633
+ sortDir,
7634
+ context
6936
7635
  });
6937
7636
  return res;
6938
7637
  }),
@@ -6946,7 +7645,7 @@ function useVenueMarkets(options) {
6946
7645
  },
6947
7646
  queryClient != null ? queryClient : fallbackQueryClient
6948
7647
  );
6949
- const markets = (_e = (_d = query.data) == null ? void 0 : _d.pages.flatMap((page) => page.data)) != null ? _e : [];
7648
+ const markets = (_j = (_i = query.data) == null ? void 0 : _i.pages.flatMap((page) => page.data)) != null ? _j : [];
6950
7649
  const hasNextPage = !!query.hasNextPage;
6951
7650
  return __spreadProps(__spreadValues({}, query), {
6952
7651
  markets,
@@ -6958,7 +7657,8 @@ function useVenueMarkets(options) {
6958
7657
  function mergeEventWithFullMarkets(event, fullMarkets) {
6959
7658
  if (fullMarkets.length === 0) return event;
6960
7659
  const fullById = new Map(fullMarkets.map((m) => [m.id, m]));
6961
- const mergedMarkets = event.venueMarkets.map((minimal) => {
7660
+ const ordering = event.venueMarkets.length > 0 ? event.venueMarkets : fullMarkets;
7661
+ const mergedMarkets = ordering.map((minimal) => {
6962
7662
  var _a;
6963
7663
  return (_a = fullById.get(minimal.id)) != null ? _a : minimal;
6964
7664
  });
@@ -6967,14 +7667,18 @@ function mergeEventWithFullMarkets(event, fullMarkets) {
6967
7667
  function useEnrichedVenueEvent(options) {
6968
7668
  var _b;
6969
7669
  const _a = useVenueEvent(options), { event, isLoading, error } = _a, rest = __objRest(_a, ["event", "isLoading", "error"]);
7670
+ const eventEndedAt = (event == null ? void 0 : event.endDate) && Number.isFinite(Date.parse(event.endDate)) ? Date.parse(event.endDate) : null;
7671
+ const shouldFetchOnlyOpenMarkets = eventEndedAt == null || eventEndedAt >= Date.now();
6970
7672
  const { markets, isLoading: isEnriching } = useVenueMarkets({
6971
7673
  venueEventId: options.eventId,
6972
7674
  enabled: ((_b = options.enabled) != null ? _b : true) && !!event,
6973
- status: "open" /* open */,
6974
- sortBy: "yesPrice",
6975
- sortDir: "desc"
7675
+ status: shouldFetchOnlyOpenMarkets ? "open" /* open */ : void 0
7676
+ // No explicit sortBy: event-scoped /venue-markets sorts by the event's
7677
+ // type-aware order (structureOrderBy). Keeping this in lockstep with
7678
+ // MarketDetailsList preserves the shared React Query cache key and the
7679
+ // event-type ordering.
6976
7680
  });
6977
- const enrichedEvent = (0, import_react35.useMemo)(() => {
7681
+ const enrichedEvent = (0, import_react34.useMemo)(() => {
6978
7682
  if (!event) return void 0;
6979
7683
  if (markets.length === 0) return event;
6980
7684
  return mergeEventWithFullMarkets(event, markets);
@@ -6989,12 +7693,12 @@ function useEnrichedVenueEvent(options) {
6989
7693
 
6990
7694
  // src/use-venue-events.ts
6991
7695
  var import_react_query36 = require("@tanstack/react-query");
6992
- var import_react36 = require("react");
7696
+ var import_react35 = require("react");
6993
7697
  function useVenueEvents(options) {
6994
7698
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
6995
- const client = (0, import_react36.useContext)(AggClientContext);
6996
- const queryClient = (0, import_react36.useContext)(import_react_query36.QueryClientContext);
6997
- const [fallbackQueryClient] = (0, import_react36.useState)(() => new import_react_query36.QueryClient());
7699
+ const client = (0, import_react35.useContext)(AggClientContext);
7700
+ const queryClient = (0, import_react35.useContext)(import_react_query36.QueryClientContext);
7701
+ const [fallbackQueryClient] = (0, import_react35.useState)(() => new import_react_query36.QueryClient());
6998
7702
  const venues = options == null ? void 0 : options.venues;
6999
7703
  const search = options == null ? void 0 : options.search;
7000
7704
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -7009,8 +7713,9 @@ function useVenueEvents(options) {
7009
7713
  const minYesPrice = options == null ? void 0 : options.minYesPrice;
7010
7714
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
7011
7715
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
7716
+ const grouped = options == null ? void 0 : options.grouped;
7012
7717
  const initialPages = options == null ? void 0 : options.initialPages;
7013
- (0, import_react36.useEffect)(() => {
7718
+ (0, import_react35.useEffect)(() => {
7014
7719
  if (queryClient) return void 0;
7015
7720
  fallbackQueryClient.mount();
7016
7721
  return () => {
@@ -7035,6 +7740,7 @@ function useVenueEvents(options) {
7035
7740
  minYesPrice != null ? minYesPrice : "",
7036
7741
  maxYesPrice != null ? maxYesPrice : "",
7037
7742
  endDateFrom != null ? endDateFrom : "",
7743
+ grouped != null ? grouped : false,
7038
7744
  limit
7039
7745
  ],
7040
7746
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
@@ -7054,6 +7760,7 @@ function useVenueEvents(options) {
7054
7760
  minYesPrice,
7055
7761
  maxYesPrice,
7056
7762
  endDateFrom,
7763
+ grouped,
7057
7764
  cursor: pageParam
7058
7765
  });
7059
7766
  return res;
@@ -7070,8 +7777,8 @@ function useVenueEvents(options) {
7070
7777
  },
7071
7778
  queryClient != null ? queryClient : fallbackQueryClient
7072
7779
  );
7073
- const prefetchedRef = (0, import_react36.useRef)(false);
7074
- (0, import_react36.useEffect)(() => {
7780
+ const prefetchedRef = (0, import_react35.useRef)(false);
7781
+ (0, import_react35.useEffect)(() => {
7075
7782
  var _a2, _b2;
7076
7783
  if (prefetchedRef.current) return;
7077
7784
  if (!initialPages || initialPages <= 1) return;
@@ -7089,7 +7796,7 @@ function useVenueEvents(options) {
7089
7796
  query.hasNextPage,
7090
7797
  query.fetchNextPage
7091
7798
  ]);
7092
- const events = (0, import_react36.useMemo)(
7799
+ const events = (0, import_react35.useMemo)(
7093
7800
  () => {
7094
7801
  var _a2, _b2;
7095
7802
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -7207,7 +7914,7 @@ var computePriceGaps = ({
7207
7914
  };
7208
7915
 
7209
7916
  // src/use-viewport-midpoints.ts
7210
- var import_react37 = require("react");
7917
+ var import_react36 = require("react");
7211
7918
  var buildOutcomeMidpointMap = (outcomes) => {
7212
7919
  const m = /* @__PURE__ */ new Map();
7213
7920
  if (!outcomes) return m;
@@ -7260,15 +7967,15 @@ function useViewportMidpoints(visibleMarkets, options) {
7260
7967
  market: { maxMidpointIdsPerRequest: configuredMaxMidpointIdsPerRequest }
7261
7968
  } = useAggUiConfig();
7262
7969
  const maxMidpointIdsPerRequest = (_a = options == null ? void 0 : options.maxMidpointIdsPerRequest) != null ? _a : configuredMaxMidpointIdsPerRequest;
7263
- const [cache, setCache] = (0, import_react37.useState)(() => /* @__PURE__ */ new Map());
7264
- const inFlightRef = (0, import_react37.useRef)(/* @__PURE__ */ new Set());
7265
- const visibleRef = (0, import_react37.useRef)(visibleMarkets);
7970
+ const [cache, setCache] = (0, import_react36.useState)(() => /* @__PURE__ */ new Map());
7971
+ const inFlightRef = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
7972
+ const visibleRef = (0, import_react36.useRef)(visibleMarkets);
7266
7973
  visibleRef.current = visibleMarkets;
7267
- const visibleFp = (0, import_react37.useMemo)(
7974
+ const visibleFp = (0, import_react36.useMemo)(
7268
7975
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
7269
7976
  [visibleMarkets]
7270
7977
  );
7271
- (0, import_react37.useEffect)(() => {
7978
+ (0, import_react36.useEffect)(() => {
7272
7979
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
7273
7980
  if (!toFetch.length) return;
7274
7981
  let cancelled = false;
@@ -7292,7 +7999,7 @@ function useViewportMidpoints(visibleMarkets, options) {
7292
7999
  cancelled = true;
7293
8000
  };
7294
8001
  }, [visibleFp, cache, maxMidpointIdsPerRequest]);
7295
- const { prices, venueByOutcomeId } = (0, import_react37.useMemo)(() => {
8002
+ const { prices, venueByOutcomeId } = (0, import_react36.useMemo)(() => {
7296
8003
  var _a2, _b, _c, _d;
7297
8004
  const map = /* @__PURE__ */ new Map();
7298
8005
  const venueMap = /* @__PURE__ */ new Map();
@@ -7325,15 +8032,15 @@ function useViewportMidpoints(visibleMarkets, options) {
7325
8032
  }
7326
8033
 
7327
8034
  // src/use-visible-ids.ts
7328
- var import_react38 = require("react");
8035
+ var import_react37 = require("react");
7329
8036
  function useVisibleIds(options = {}) {
7330
8037
  const { rootMargin = "0px", threshold = 0 } = options;
7331
- const [visibleIds, setVisibleIds] = (0, import_react38.useState)(() => /* @__PURE__ */ new Set());
7332
- const observerRef = (0, import_react38.useRef)(null);
7333
- const elementsRef = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
7334
- const elementIdRef = (0, import_react38.useRef)(/* @__PURE__ */ new WeakMap());
7335
- const callbackRefsRef = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
7336
- (0, import_react38.useEffect)(() => {
8038
+ const [visibleIds, setVisibleIds] = (0, import_react37.useState)(() => /* @__PURE__ */ new Set());
8039
+ const observerRef = (0, import_react37.useRef)(null);
8040
+ const elementsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
8041
+ const elementIdRef = (0, import_react37.useRef)(/* @__PURE__ */ new WeakMap());
8042
+ const callbackRefsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
8043
+ (0, import_react37.useEffect)(() => {
7337
8044
  if (typeof IntersectionObserver === "undefined") return;
7338
8045
  const observer = new IntersectionObserver(
7339
8046
  (entries) => {
@@ -7365,7 +8072,7 @@ function useVisibleIds(options = {}) {
7365
8072
  observerRef.current = null;
7366
8073
  };
7367
8074
  }, [rootMargin, threshold]);
7368
- const register = (0, import_react38.useCallback)((id) => {
8075
+ const register = (0, import_react37.useCallback)((id) => {
7369
8076
  const existing = callbackRefsRef.current.get(id);
7370
8077
  if (existing) return existing;
7371
8078
  const callback = (el) => {
@@ -7461,11 +8168,13 @@ var toAppConfigResult = (query) => {
7461
8168
  TradeSide,
7462
8169
  TurnstileChallengeError,
7463
8170
  Venue,
8171
+ buildLiveBestPriceCandidates,
7464
8172
  computeClosedPositionTotals,
7465
8173
  computePriceGaps,
7466
8174
  defaultAggUiConfig,
7467
8175
  defaultSdkUiConfig,
7468
8176
  executionKeys,
8177
+ extractOutcomeBestCandidate,
7469
8178
  findLivePriceById,
7470
8179
  getBuilder,
7471
8180
  getDepositAddress,
@@ -7527,6 +8236,7 @@ var toAppConfigResult = (query) => {
7527
8236
  useGeoBlock,
7528
8237
  useLabels,
7529
8238
  useLinkAccount,
8239
+ useLiveBestPriceCandidates,
7530
8240
  useLiveBestPrices,
7531
8241
  useLiveCandleOverlay,
7532
8242
  useLiveCandles,
@@ -7564,7 +8274,6 @@ var toAppConfigResult = (query) => {
7564
8274
  useSearch,
7565
8275
  useSmartRoute,
7566
8276
  useSyncBalances,
7567
- useTradableVenues,
7568
8277
  useUserActivity,
7569
8278
  useUserHoldings,
7570
8279
  useVenueEvent,