@agg-build/hooks 2.2.1 → 2.3.0

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.d.mts CHANGED
@@ -4036,6 +4036,8 @@ interface UseSearchOptions {
4036
4036
  type: "events" | "markets";
4037
4037
  /** Optional category ID filter. */
4038
4038
  categoryIds?: string[];
4039
+ /** Filter by status — pass ["open"] for tradeable-only results. */
4040
+ status?: MarketStatus[];
4039
4041
  /** Page size. Default 20. */
4040
4042
  limit?: number;
4041
4043
  /** If provided, enable/disable the query. Defaults to true. */
@@ -4083,6 +4085,8 @@ interface UseMarketSearchOptions {
4083
4085
  type: "events" | "markets";
4084
4086
  /** Optional category ID filter. */
4085
4087
  categoryIds?: string[];
4088
+ /** Filter by status — pass ["open"] for tradeable-only results. */
4089
+ status?: MarketStatus[];
4086
4090
  /** Page size for both modes. Default 20. */
4087
4091
  limit?: number;
4088
4092
  /**
package/dist/index.d.ts CHANGED
@@ -4036,6 +4036,8 @@ interface UseSearchOptions {
4036
4036
  type: "events" | "markets";
4037
4037
  /** Optional category ID filter. */
4038
4038
  categoryIds?: string[];
4039
+ /** Filter by status — pass ["open"] for tradeable-only results. */
4040
+ status?: MarketStatus[];
4039
4041
  /** Page size. Default 20. */
4040
4042
  limit?: number;
4041
4043
  /** If provided, enable/disable the query. Defaults to true. */
@@ -4083,6 +4085,8 @@ interface UseMarketSearchOptions {
4083
4085
  type: "events" | "markets";
4084
4086
  /** Optional category ID filter. */
4085
4087
  categoryIds?: string[];
4088
+ /** Filter by status — pass ["open"] for tradeable-only results. */
4089
+ status?: MarketStatus[];
4086
4090
  /** Page size for both modes. Default 20. */
4087
4091
  limit?: number;
4088
4092
  /**
package/dist/index.js CHANGED
@@ -6521,6 +6521,18 @@ var normalizeVenueMarketIds = (venueMarkets) => {
6521
6521
  var normalizeOutcomeLabel = (label) => {
6522
6522
  return typeof label === "string" ? label.trim().toLowerCase() : "";
6523
6523
  };
6524
+ var normalizeSemanticOutcomeLabel = (label) => {
6525
+ const normalizedLabel = normalizeOutcomeLabel(label);
6526
+ if (!normalizedLabel) return "";
6527
+ if (normalizedLabel === "y") return "yes";
6528
+ if (normalizedLabel === "n") return "no";
6529
+ return normalizedLabel;
6530
+ };
6531
+ var outcomeMatchesSemanticSide = (left, right) => {
6532
+ const leftCandidates = [left.label, left.title].map((value) => normalizeSemanticOutcomeLabel(value)).filter(Boolean);
6533
+ const rightCandidates = [right.label, right.title].map((value) => normalizeSemanticOutcomeLabel(value)).filter(Boolean);
6534
+ return leftCandidates.some((candidate) => rightCandidates.includes(candidate));
6535
+ };
6524
6536
  var resolveBestMidpointCandidateOutcomeIds = (venueMarkets) => {
6525
6537
  var _a, _b;
6526
6538
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
@@ -6550,6 +6562,31 @@ var resolveSiblingOutcomeMidpoint = (matched, ref) => {
6550
6562
  if ((sibOutcome == null ? void 0 : sibOutcome.midpoint) == null) return null;
6551
6563
  return { midpoint: sibOutcome.midpoint, venue: (_b = sibling.venue) != null ? _b : null };
6552
6564
  };
6565
+ var resolveSemanticFallbackMidpoint = ({
6566
+ marketById,
6567
+ outcome,
6568
+ matched
6569
+ }) => {
6570
+ var _a;
6571
+ if (!(matched == null ? void 0 : matched.length)) return null;
6572
+ let best = null;
6573
+ for (const sibling of matched) {
6574
+ const siblingMarket = marketById.get(sibling.venueMarketId);
6575
+ if (!((_a = siblingMarket == null ? void 0 : siblingMarket.venueMarketOutcomes) == null ? void 0 : _a.length)) continue;
6576
+ for (const siblingOutcome of siblingMarket.venueMarketOutcomes) {
6577
+ if (!outcomeMatchesSemanticSide(outcome, siblingOutcome)) continue;
6578
+ const candidate = resolveSiblingOutcomeMidpoint(matched, {
6579
+ venueMarketId: sibling.venueMarketId,
6580
+ venueMarketOutcomeId: siblingOutcome.id
6581
+ });
6582
+ if (candidate == null) continue;
6583
+ if (best == null || candidate.midpoint < best.midpoint) {
6584
+ best = candidate;
6585
+ }
6586
+ }
6587
+ }
6588
+ return best;
6589
+ };
6553
6590
  var extractBestPrices = (data, venueMarkets) => {
6554
6591
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
6555
6592
  const bestPrices = /* @__PURE__ */ new Map();
@@ -6658,11 +6695,12 @@ function useMidpoints(venueMarkets, options) {
6658
6695
  refetchOnReconnect: false
6659
6696
  });
6660
6697
  const result = (0, import_react28.useMemo)(() => {
6661
- var _a2, _b, _c, _d, _e;
6698
+ var _a2, _b, _c, _d, _e, _f;
6662
6699
  const map = /* @__PURE__ */ new Map();
6663
6700
  const venueMap = /* @__PURE__ */ new Map();
6664
6701
  if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
6665
6702
  const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
6703
+ const marketById = new Map(venueMarkets.map((market) => [market.id, market]));
6666
6704
  for (const item of data.data) {
6667
6705
  if (!((_a2 = item.outcomes) == null ? void 0 : _a2.length)) continue;
6668
6706
  for (const o of item.outcomes) {
@@ -6676,15 +6714,26 @@ function useMidpoints(venueMarkets, options) {
6676
6714
  if (!item) continue;
6677
6715
  for (const outcome of market.venueMarketOutcomes) {
6678
6716
  const refs = (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : [];
6679
- if (!refs.length) continue;
6680
6717
  let best = (_c = map.get(outcome.id)) != null ? _c : null;
6681
6718
  let bestVenue = (_d = item.venue) != null ? _d : null;
6682
- for (const ref of refs) {
6683
- const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
6684
- if (sib == null) continue;
6685
- if (best == null || sib.midpoint < best) {
6686
- best = sib.midpoint;
6687
- bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
6719
+ if (refs.length > 0) {
6720
+ for (const ref of refs) {
6721
+ const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
6722
+ if (sib == null) continue;
6723
+ if (best == null || sib.midpoint < best) {
6724
+ best = sib.midpoint;
6725
+ bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
6726
+ }
6727
+ }
6728
+ } else if (best == null) {
6729
+ const fallback = resolveSemanticFallbackMidpoint({
6730
+ marketById,
6731
+ outcome,
6732
+ matched: item.matched
6733
+ });
6734
+ if (fallback != null) {
6735
+ best = fallback.midpoint;
6736
+ bestVenue = (_f = fallback.venue) != null ? _f : bestVenue;
6688
6737
  }
6689
6738
  }
6690
6739
  if (best != null) {
@@ -7135,11 +7184,11 @@ function useOrders(options = {}) {
7135
7184
  var import_react_query31 = require("@tanstack/react-query");
7136
7185
  var import_react31 = require("react");
7137
7186
  function useSearch(options) {
7138
- var _a, _b, _c;
7187
+ var _a, _b, _c, _d;
7139
7188
  const client = (0, import_react31.useContext)(AggClientContext);
7140
7189
  const queryClient = (0, import_react31.useContext)(import_react_query31.QueryClientContext);
7141
7190
  const [fallbackQueryClient] = (0, import_react31.useState)(() => new import_react_query31.QueryClient());
7142
- const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
7191
+ const { q, type, categoryIds, status, limit = 20, enabled = true, deep = false } = options;
7143
7192
  const isEnabled = enabled && q.length > 0;
7144
7193
  (0, import_react31.useEffect)(() => {
7145
7194
  if (queryClient) return void 0;
@@ -7155,7 +7204,15 @@ function useSearch(options) {
7155
7204
  {
7156
7205
  // deep is part of the key — TanStack treats deep vs light as
7157
7206
  // independent queries so users can have both modes cached side-by-side.
7158
- queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit, deep],
7207
+ queryKey: [
7208
+ "search",
7209
+ q,
7210
+ type,
7211
+ (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "",
7212
+ (_b = status == null ? void 0 : status.join(",")) != null ? _b : "",
7213
+ limit,
7214
+ deep
7215
+ ],
7159
7216
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
7160
7217
  if (!client) {
7161
7218
  throw new Error("useSearch must be used within an <AggProvider>");
@@ -7164,6 +7221,7 @@ function useSearch(options) {
7164
7221
  q,
7165
7222
  type,
7166
7223
  categoryIds,
7224
+ status,
7167
7225
  limit,
7168
7226
  cursor: pageParam,
7169
7227
  deep
@@ -7181,7 +7239,7 @@ function useSearch(options) {
7181
7239
  },
7182
7240
  queryClient != null ? queryClient : fallbackQueryClient
7183
7241
  );
7184
- const data = (_c = (_b = query.data) == null ? void 0 : _b.pages.flatMap((page) => page.data)) != null ? _c : [];
7242
+ const data = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((page) => page.data)) != null ? _d : [];
7185
7243
  return {
7186
7244
  data,
7187
7245
  isLoading: query.isLoading,
@@ -7201,6 +7259,7 @@ function useMarketSearch(options) {
7201
7259
  const {
7202
7260
  type,
7203
7261
  categoryIds,
7262
+ status,
7204
7263
  limit = 20,
7205
7264
  debounceMs = 200,
7206
7265
  enableSuggestions = true,
@@ -7215,6 +7274,7 @@ function useMarketSearch(options) {
7215
7274
  q: trimmedDebounced,
7216
7275
  type,
7217
7276
  categoryIds,
7277
+ status,
7218
7278
  limit,
7219
7279
  enabled: suggestionsEnabled,
7220
7280
  deep: false
@@ -7224,6 +7284,7 @@ function useMarketSearch(options) {
7224
7284
  q: submittedQ,
7225
7285
  type,
7226
7286
  categoryIds,
7287
+ status,
7227
7288
  limit,
7228
7289
  enabled: submittedQ.length > 0,
7229
7290
  deep: true
package/dist/index.mjs CHANGED
@@ -1322,6 +1322,18 @@ var normalizeVenueMarketIds = (venueMarkets) => {
1322
1322
  var normalizeOutcomeLabel = (label) => {
1323
1323
  return typeof label === "string" ? label.trim().toLowerCase() : "";
1324
1324
  };
1325
+ var normalizeSemanticOutcomeLabel = (label) => {
1326
+ const normalizedLabel = normalizeOutcomeLabel(label);
1327
+ if (!normalizedLabel) return "";
1328
+ if (normalizedLabel === "y") return "yes";
1329
+ if (normalizedLabel === "n") return "no";
1330
+ return normalizedLabel;
1331
+ };
1332
+ var outcomeMatchesSemanticSide = (left, right) => {
1333
+ const leftCandidates = [left.label, left.title].map((value) => normalizeSemanticOutcomeLabel(value)).filter(Boolean);
1334
+ const rightCandidates = [right.label, right.title].map((value) => normalizeSemanticOutcomeLabel(value)).filter(Boolean);
1335
+ return leftCandidates.some((candidate) => rightCandidates.includes(candidate));
1336
+ };
1325
1337
  var resolveBestMidpointCandidateOutcomeIds = (venueMarkets) => {
1326
1338
  var _a, _b;
1327
1339
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
@@ -1351,6 +1363,31 @@ var resolveSiblingOutcomeMidpoint = (matched, ref) => {
1351
1363
  if ((sibOutcome == null ? void 0 : sibOutcome.midpoint) == null) return null;
1352
1364
  return { midpoint: sibOutcome.midpoint, venue: (_b = sibling.venue) != null ? _b : null };
1353
1365
  };
1366
+ var resolveSemanticFallbackMidpoint = ({
1367
+ marketById,
1368
+ outcome,
1369
+ matched
1370
+ }) => {
1371
+ var _a;
1372
+ if (!(matched == null ? void 0 : matched.length)) return null;
1373
+ let best = null;
1374
+ for (const sibling of matched) {
1375
+ const siblingMarket = marketById.get(sibling.venueMarketId);
1376
+ if (!((_a = siblingMarket == null ? void 0 : siblingMarket.venueMarketOutcomes) == null ? void 0 : _a.length)) continue;
1377
+ for (const siblingOutcome of siblingMarket.venueMarketOutcomes) {
1378
+ if (!outcomeMatchesSemanticSide(outcome, siblingOutcome)) continue;
1379
+ const candidate = resolveSiblingOutcomeMidpoint(matched, {
1380
+ venueMarketId: sibling.venueMarketId,
1381
+ venueMarketOutcomeId: siblingOutcome.id
1382
+ });
1383
+ if (candidate == null) continue;
1384
+ if (best == null || candidate.midpoint < best.midpoint) {
1385
+ best = candidate;
1386
+ }
1387
+ }
1388
+ }
1389
+ return best;
1390
+ };
1354
1391
  var extractBestPrices = (data, venueMarkets) => {
1355
1392
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1356
1393
  const bestPrices = /* @__PURE__ */ new Map();
@@ -1459,11 +1496,12 @@ function useMidpoints(venueMarkets, options) {
1459
1496
  refetchOnReconnect: false
1460
1497
  });
1461
1498
  const result = useMemo8(() => {
1462
- var _a2, _b, _c, _d, _e;
1499
+ var _a2, _b, _c, _d, _e, _f;
1463
1500
  const map = /* @__PURE__ */ new Map();
1464
1501
  const venueMap = /* @__PURE__ */ new Map();
1465
1502
  if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
1466
1503
  const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
1504
+ const marketById = new Map(venueMarkets.map((market) => [market.id, market]));
1467
1505
  for (const item of data.data) {
1468
1506
  if (!((_a2 = item.outcomes) == null ? void 0 : _a2.length)) continue;
1469
1507
  for (const o of item.outcomes) {
@@ -1477,15 +1515,26 @@ function useMidpoints(venueMarkets, options) {
1477
1515
  if (!item) continue;
1478
1516
  for (const outcome of market.venueMarketOutcomes) {
1479
1517
  const refs = (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : [];
1480
- if (!refs.length) continue;
1481
1518
  let best = (_c = map.get(outcome.id)) != null ? _c : null;
1482
1519
  let bestVenue = (_d = item.venue) != null ? _d : null;
1483
- for (const ref of refs) {
1484
- const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
1485
- if (sib == null) continue;
1486
- if (best == null || sib.midpoint < best) {
1487
- best = sib.midpoint;
1488
- bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
1520
+ if (refs.length > 0) {
1521
+ for (const ref of refs) {
1522
+ const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
1523
+ if (sib == null) continue;
1524
+ if (best == null || sib.midpoint < best) {
1525
+ best = sib.midpoint;
1526
+ bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
1527
+ }
1528
+ }
1529
+ } else if (best == null) {
1530
+ const fallback = resolveSemanticFallbackMidpoint({
1531
+ marketById,
1532
+ outcome,
1533
+ matched: item.matched
1534
+ });
1535
+ if (fallback != null) {
1536
+ best = fallback.midpoint;
1537
+ bestVenue = (_f = fallback.venue) != null ? _f : bestVenue;
1489
1538
  }
1490
1539
  }
1491
1540
  if (best != null) {
@@ -1941,11 +1990,11 @@ import {
1941
1990
  } from "@tanstack/react-query";
1942
1991
  import { useContext as useContext2, useEffect as useEffect7, useState as useState6 } from "react";
1943
1992
  function useSearch(options) {
1944
- var _a, _b, _c;
1993
+ var _a, _b, _c, _d;
1945
1994
  const client = useContext2(AggClientContext);
1946
1995
  const queryClient = useContext2(QueryClientContext);
1947
1996
  const [fallbackQueryClient] = useState6(() => new QueryClient());
1948
- const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
1997
+ const { q, type, categoryIds, status, limit = 20, enabled = true, deep = false } = options;
1949
1998
  const isEnabled = enabled && q.length > 0;
1950
1999
  useEffect7(() => {
1951
2000
  if (queryClient) return void 0;
@@ -1961,7 +2010,15 @@ function useSearch(options) {
1961
2010
  {
1962
2011
  // deep is part of the key — TanStack treats deep vs light as
1963
2012
  // independent queries so users can have both modes cached side-by-side.
1964
- queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit, deep],
2013
+ queryKey: [
2014
+ "search",
2015
+ q,
2016
+ type,
2017
+ (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "",
2018
+ (_b = status == null ? void 0 : status.join(",")) != null ? _b : "",
2019
+ limit,
2020
+ deep
2021
+ ],
1965
2022
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
1966
2023
  if (!client) {
1967
2024
  throw new Error("useSearch must be used within an <AggProvider>");
@@ -1970,6 +2027,7 @@ function useSearch(options) {
1970
2027
  q,
1971
2028
  type,
1972
2029
  categoryIds,
2030
+ status,
1973
2031
  limit,
1974
2032
  cursor: pageParam,
1975
2033
  deep
@@ -1987,7 +2045,7 @@ function useSearch(options) {
1987
2045
  },
1988
2046
  queryClient != null ? queryClient : fallbackQueryClient
1989
2047
  );
1990
- const data = (_c = (_b = query.data) == null ? void 0 : _b.pages.flatMap((page) => page.data)) != null ? _c : [];
2048
+ const data = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((page) => page.data)) != null ? _d : [];
1991
2049
  return {
1992
2050
  data,
1993
2051
  isLoading: query.isLoading,
@@ -2007,6 +2065,7 @@ function useMarketSearch(options) {
2007
2065
  const {
2008
2066
  type,
2009
2067
  categoryIds,
2068
+ status,
2010
2069
  limit = 20,
2011
2070
  debounceMs = 200,
2012
2071
  enableSuggestions = true,
@@ -2021,6 +2080,7 @@ function useMarketSearch(options) {
2021
2080
  q: trimmedDebounced,
2022
2081
  type,
2023
2082
  categoryIds,
2083
+ status,
2024
2084
  limit,
2025
2085
  enabled: suggestionsEnabled,
2026
2086
  deep: false
@@ -2030,6 +2090,7 @@ function useMarketSearch(options) {
2030
2090
  q: submittedQ,
2031
2091
  type,
2032
2092
  categoryIds,
2093
+ status,
2033
2094
  limit,
2034
2095
  enabled: submittedQ.length > 0,
2035
2096
  deep: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/hooks",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
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",
@@ -83,7 +83,7 @@
83
83
  "react": "^18.0.0 || ^19.0.0",
84
84
  "viem": "^2.0.0",
85
85
  "wagmi": "^3.0.0 || ^2.0.0",
86
- "@agg-build/sdk": "^2.2.1"
86
+ "@agg-build/sdk": "^2.3.0"
87
87
  },
88
88
  "peerDependenciesMeta": {
89
89
  "@solana/wallet-adapter-react": {