@agg-build/hooks 4.18.0 → 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/index.js CHANGED
@@ -8415,6 +8415,21 @@ var normalizeVenueMarketIds = (venueMarkets) => {
8415
8415
  }
8416
8416
  return [...ids].sort((left, right) => left.localeCompare(right));
8417
8417
  };
8418
+ var EMPTY_MIDPOINTS_POLL_MS = 5e3;
8419
+ var EMPTY_MIDPOINTS_MAX_FETCHES = 12;
8420
+ var hasUsableMidpoint = (item) => {
8421
+ var _a;
8422
+ if (!item) return false;
8423
+ if (item.midpoint != null) return true;
8424
+ return ((_a = item.outcomes) != null ? _a : []).some(
8425
+ (outcome) => outcome.midpoint != null || outcome.bestBid != null || outcome.bestAsk != null
8426
+ );
8427
+ };
8428
+ var isMidpointResponseComplete = (data, primaryVenueMarketIds) => {
8429
+ if (!(data == null ? void 0 : data.data)) return false;
8430
+ const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
8431
+ return primaryVenueMarketIds.every((id) => hasUsableMidpoint(itemByMarketId.get(id)));
8432
+ };
8418
8433
  var normalizeOutcomeLabel = (label) => {
8419
8434
  return typeof label === "string" ? label.trim().toLowerCase() : "";
8420
8435
  };
@@ -8581,13 +8596,21 @@ function useMidpoints(venueMarkets, options) {
8581
8596
  () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
8582
8597
  [venueMarkets]
8583
8598
  );
8599
+ const primaryVenueMarketIds = (0, import_react35.useMemo)(
8600
+ () => (venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean),
8601
+ [venueMarkets]
8602
+ );
8584
8603
  const { data, isLoading } = (0, import_react_query34.useQuery)({
8585
8604
  queryKey: ["midpoints", ids, maxMidpointIdsPerRequest],
8586
8605
  queryFn: () => client.getMidpoints(ids, { bestPrice: true, maxMidpointIdsPerRequest }),
8587
8606
  enabled: ids.length > 0,
8588
- staleTime: Infinity,
8607
+ // Complete responses stay cached for the session (unchanged behavior).
8608
+ // Incomplete ones are stale, so a remount refetches them and a short,
8609
+ // bounded poll picks up prices once a cold venue book warms.
8610
+ staleTime: (query) => isMidpointResponseComplete(query.state.data, primaryVenueMarketIds) ? Infinity : 0,
8611
+ refetchInterval: (query) => !isMidpointResponseComplete(query.state.data, primaryVenueMarketIds) && query.state.dataUpdateCount < EMPTY_MIDPOINTS_MAX_FETCHES ? EMPTY_MIDPOINTS_POLL_MS : false,
8589
8612
  gcTime: 30 * 6e4,
8590
- refetchOnMount: false,
8613
+ refetchOnMount: true,
8591
8614
  refetchOnWindowFocus: false,
8592
8615
  refetchOnReconnect: false
8593
8616
  });
package/dist/index.mjs CHANGED
@@ -2317,6 +2317,21 @@ var normalizeVenueMarketIds = (venueMarkets) => {
2317
2317
  }
2318
2318
  return [...ids].sort((left, right) => left.localeCompare(right));
2319
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
+ };
2320
2335
  var normalizeOutcomeLabel = (label) => {
2321
2336
  return typeof label === "string" ? label.trim().toLowerCase() : "";
2322
2337
  };
@@ -2483,13 +2498,21 @@ function useMidpoints(venueMarkets, options) {
2483
2498
  () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
2484
2499
  [venueMarkets]
2485
2500
  );
2501
+ const primaryVenueMarketIds = useMemo9(
2502
+ () => (venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean),
2503
+ [venueMarkets]
2504
+ );
2486
2505
  const { data, isLoading } = useQuery6({
2487
2506
  queryKey: ["midpoints", ids, maxMidpointIdsPerRequest],
2488
2507
  queryFn: () => client.getMidpoints(ids, { bestPrice: true, maxMidpointIdsPerRequest }),
2489
2508
  enabled: ids.length > 0,
2490
- staleTime: Infinity,
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,
2491
2514
  gcTime: 30 * 6e4,
2492
- refetchOnMount: false,
2515
+ refetchOnMount: true,
2493
2516
  refetchOnWindowFocus: false,
2494
2517
  refetchOnReconnect: false
2495
2518
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/hooks",
3
- "version": "4.18.0",
3
+ "version": "4.18.2",
4
4
  "description": "React hooks and providers for the AGG prediction market aggregator. Wraps @agg-build/sdk with TanStack Query, shared session state, and live WebSocket data.",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",