@liberfi.io/react-predict 0.3.69 → 0.3.71

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/server.js CHANGED
@@ -199,6 +199,21 @@ function resolvePredictSearchParams(params = {}) {
199
199
  async function fetchPredictSearch(client, params) {
200
200
  return client.search(resolvePredictSearchParams(params));
201
201
  }
202
+
203
+ // src/client/types.ts
204
+ var MARKET_STRUCTURE_MEDIA_TYPE_V1 = "application/vnd.liberfi.market-structure+json;v=1";
205
+
206
+ // src/client/client.ts
207
+ var MarketDataHttpError = class extends Error {
208
+ constructor(message, status, code, retryAfter, body) {
209
+ super(message);
210
+ this.status = status;
211
+ this.code = code;
212
+ this.retryAfter = retryAfter;
213
+ this.body = body;
214
+ }
215
+ name = "MarketDataHttpError";
216
+ };
202
217
  function buildQuery(params) {
203
218
  const qs = new URLSearchParams();
204
219
  for (const [key, value] of Object.entries(params)) {
@@ -225,6 +240,26 @@ var PredictClient = class {
225
240
  }
226
241
  };
227
242
  }
243
+ async marketDataRequest(path, options) {
244
+ const response = await fetch(
245
+ `${this.endpoint}${path}`,
246
+ this.requestOptions(options)
247
+ );
248
+ if (response.ok) {
249
+ return await response.json();
250
+ }
251
+ const body = await parseMarketDataResponseBody(response);
252
+ const record = isRecord(body) ? body : void 0;
253
+ const code = typeof record?.error === "string" ? record.error : typeof record?.code === "string" ? record.code : void 0;
254
+ const message = typeof record?.message === "string" ? record.message : code ?? response.statusText ?? `HTTP ${response.status}`;
255
+ throw new MarketDataHttpError(
256
+ message,
257
+ response.status,
258
+ code,
259
+ response.headers.get("Retry-After") ?? void 0,
260
+ body
261
+ );
262
+ }
228
263
  // -------------------------------------------------------------------------
229
264
  // Events
230
265
  // -------------------------------------------------------------------------
@@ -359,6 +394,85 @@ var PredictClient = class {
359
394
  // -------------------------------------------------------------------------
360
395
  // Markets
361
396
  // -------------------------------------------------------------------------
397
+ /** Register or refresh the complete provider-neutral market-data demand set. */
398
+ async watchMarketData(request) {
399
+ return await this.marketDataRequest(
400
+ "/api/v1/market-data/watch",
401
+ {
402
+ method: "POST",
403
+ headers: { "Content-Type": "application/json" },
404
+ body: JSON.stringify(request)
405
+ }
406
+ );
407
+ }
408
+ /** Read cache-only quote snapshots for at most 500 provider-neutral keys. */
409
+ async getMarketDataQuotes(markets) {
410
+ if (markets.length > 500) {
411
+ throw new RangeError(
412
+ "market data quote request accepts at most 500 markets"
413
+ );
414
+ }
415
+ return await this.marketDataRequest(
416
+ "/api/v1/markets/quotes",
417
+ {
418
+ method: "POST",
419
+ cache: "no-store",
420
+ headers: { "Content-Type": "application/json" },
421
+ body: JSON.stringify({ markets })
422
+ }
423
+ );
424
+ }
425
+ /** Read all cached Top20 outcome books for one provider-neutral market. */
426
+ async getMarketDataOrderbooks(slug, source) {
427
+ const path = `/api/v1/markets/${encodeURIComponent(slug)}/orderbooks` + buildQuery({ source });
428
+ return await this.marketDataRequest(path, {
429
+ method: "GET",
430
+ cache: "no-store"
431
+ });
432
+ }
433
+ /**
434
+ * Revalidate a page's allowlist-only structure representation.
435
+ *
436
+ * The path must remain inside the prediction API so callers cannot turn a
437
+ * configured authenticated client into a cross-origin request primitive.
438
+ */
439
+ async getMarketStructure(path, ifNoneMatch) {
440
+ if (!path.startsWith("/api/v1/")) {
441
+ throw new TypeError("market structure path must start with /api/v1/");
442
+ }
443
+ const response = await fetch(
444
+ `${this.endpoint}${path}`,
445
+ this.requestOptions({
446
+ method: "GET",
447
+ cache: "no-store",
448
+ headers: {
449
+ Accept: MARKET_STRUCTURE_MEDIA_TYPE_V1,
450
+ ...ifNoneMatch ? { "If-None-Match": ifNoneMatch } : {}
451
+ }
452
+ })
453
+ );
454
+ const etag = response.headers.get("ETag") ?? "";
455
+ if (response.status === 304) {
456
+ return { status: 304, etag };
457
+ }
458
+ if (response.ok) {
459
+ return {
460
+ status: 200,
461
+ etag,
462
+ body: await response.json()
463
+ };
464
+ }
465
+ const body = await parseMarketDataResponseBody(response);
466
+ const record = isRecord(body) ? body : void 0;
467
+ const code = typeof record?.error === "string" ? record.error : void 0;
468
+ throw new MarketDataHttpError(
469
+ typeof record?.message === "string" ? record.message : code ?? response.statusText,
470
+ response.status,
471
+ code,
472
+ response.headers.get("Retry-After") ?? void 0,
473
+ body
474
+ );
475
+ }
362
476
  /**
363
477
  * Fetch a single prediction market by its slug.
364
478
  *
@@ -828,6 +942,18 @@ var PredictClient = class {
828
942
  function createPredictClient(endpoint, options) {
829
943
  return new PredictClient(endpoint, options);
830
944
  }
945
+ async function parseMarketDataResponseBody(response) {
946
+ const text = await response.text().catch(() => "");
947
+ if (!text) return void 0;
948
+ try {
949
+ return JSON.parse(text);
950
+ } catch {
951
+ return void 0;
952
+ }
953
+ }
954
+ function isRecord(value) {
955
+ return typeof value === "object" && value !== null && !Array.isArray(value);
956
+ }
831
957
 
832
958
  // src/client/ws.ts
833
959
  var DEFAULT_RECONNECT_BASE = 1e3;