@taphubhq/sdk-core 0.15.2 → 0.16.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.cjs CHANGED
@@ -33,10 +33,10 @@ __export(index_exports, {
33
33
  AgencyPairModule: () => AgencyPairModule,
34
34
  AuthModule: () => AuthModule,
35
35
  BidModule: () => BidModule,
36
- GameModule: () => GameModule,
37
36
  LeaderboardModule: () => LeaderboardModule,
38
37
  LocaleModule: () => LocaleModule,
39
38
  NetworkQualityMonitor: () => NetworkQualityMonitor,
39
+ PairModule: () => PairModule,
40
40
  RealtimeModule: () => RealtimeModule,
41
41
  TaphubAuthError: () => TaphubAuthError,
42
42
  TaphubClient: () => TaphubClient,
@@ -431,6 +431,15 @@ function coerceStatus(raw) {
431
431
  console.warn(`Unknown bid status "${raw}", defaulting to "pending"`);
432
432
  return "pending";
433
433
  }
434
+ var SDK_TO_WIRE_STATUS = {
435
+ pending: "pending",
436
+ win: "won",
437
+ lose: "lost",
438
+ cancelled: "cancelled"
439
+ };
440
+ function toWireStatus(status) {
441
+ return SDK_TO_WIRE_STATUS[status];
442
+ }
434
443
  function normaliseBid(node) {
435
444
  if (typeof node.id !== "string" || node.id === "" || typeof node.user_id !== "string" || node.user_id === "" || typeof node.game_id !== "string" || node.game_id === "" || typeof node.status !== "string" || node.status === "") {
436
445
  throw new TaphubServerError("Invalid response from server", {
@@ -469,8 +478,8 @@ var PLACE_BID_MUTATION = `mutation PlaceBid($input: PlaceBidInput!) {
469
478
  id user_id game_id currency amount coefficient time1 time2 price1 price2 status payout slippage created_at
470
479
  }
471
480
  }`;
472
- var MY_BIDS_QUERY = `query MyBids($status: String, $limit: Int, $offset: Int, $gameId: ID) {
473
- myBids(status: $status, limit: $limit, offset: $offset, gameId: $gameId) {
481
+ var MY_BIDS_QUERY = `query MyBids($statuses: [BidStatus!], $limit: Int, $offset: Int, $gameId: ID) {
482
+ myBids(statuses: $statuses, limit: $limit, offset: $offset, gameId: $gameId) {
474
483
  id user_id game_id currency amount coefficient time1 time2 price1 price2 status payout slippage created_at
475
484
  }
476
485
  }`;
@@ -543,8 +552,9 @@ var BidModule = class {
543
552
  }
544
553
  async listBids(opts) {
545
554
  const variables = {};
546
- if (opts?.status !== void 0) {
547
- variables.status = opts.status;
555
+ const statusList = opts?.statuses ?? (opts?.status !== void 0 ? [opts.status] : void 0);
556
+ if (statusList !== void 0 && statusList.length > 0) {
557
+ variables.statuses = statusList.map(toWireStatus);
548
558
  }
549
559
  if (opts?.limit !== void 0) {
550
560
  variables.limit = opts.limit;
@@ -564,8 +574,151 @@ var BidModule = class {
564
574
  }
565
575
  };
566
576
 
567
- // src/modules/game/normalise.ts
568
- function normaliseGame(node) {
577
+ // src/modules/leaderboard/normalise.ts
578
+ function normaliseLeaderboard(rows) {
579
+ if (!Array.isArray(rows)) {
580
+ throw new TaphubServerError("Invalid response from server", {
581
+ code: "InvalidResponse"
582
+ });
583
+ }
584
+ return rows.map((row) => ({
585
+ userId: row.user_id,
586
+ username: row.username,
587
+ rank: row.rank,
588
+ totalBids: row.total_bids,
589
+ totalWins: row.total_wins,
590
+ totalWagered: row.total_wagered,
591
+ totalPayout: row.total_payout,
592
+ gain: row.gain
593
+ }));
594
+ }
595
+
596
+ // src/modules/leaderboard/queries.ts
597
+ var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
598
+ leaderboard(period: $period, sort_by: $sort_by) {
599
+ user_id username rank total_bids total_wins total_wagered total_payout gain
600
+ }
601
+ }`;
602
+
603
+ // src/modules/leaderboard/index.ts
604
+ var LeaderboardModule = class {
605
+ #graphql;
606
+ constructor(deps) {
607
+ this.#graphql = deps.graphql;
608
+ }
609
+ async list(args) {
610
+ const body = await this.#graphql.request(
611
+ LEADERBOARD_QUERY,
612
+ { period: args.period, sort_by: args.sortBy },
613
+ args.signal ? { signal: args.signal } : void 0
614
+ );
615
+ return normaliseLeaderboard(body.leaderboard);
616
+ }
617
+ };
618
+
619
+ // src/modules/locale/normalise.ts
620
+ function normaliseLocaleResponse(node) {
621
+ let translations = null;
622
+ if (node.translations !== null) {
623
+ try {
624
+ translations = JSON.parse(node.translations);
625
+ } catch (err) {
626
+ throw new TaphubValidationError("Malformed translations JSON string from backend", {
627
+ code: "InvalidLocaleResponse",
628
+ details: {
629
+ lang: node.lang,
630
+ version: node.version,
631
+ parseError: err instanceof Error ? err.message : String(err)
632
+ }
633
+ });
634
+ }
635
+ }
636
+ return {
637
+ lang: node.lang,
638
+ version: node.version,
639
+ notModified: node.notModified,
640
+ translations
641
+ };
642
+ }
643
+ function normaliseRefreshLocalesPayload(node) {
644
+ let versions;
645
+ try {
646
+ versions = JSON.parse(node.versions);
647
+ } catch (err) {
648
+ throw new TaphubValidationError("Malformed versions JSON string from backend", {
649
+ code: "InvalidRefreshLocalesPayload",
650
+ details: {
651
+ parseError: err instanceof Error ? err.message : String(err)
652
+ }
653
+ });
654
+ }
655
+ return {
656
+ refreshed: node.refreshed,
657
+ versions
658
+ };
659
+ }
660
+
661
+ // src/modules/locale/queries.ts
662
+ var LOCALES_QUERY = `query Locales($input: LocalesInput!) {
663
+ locales(input: $input) {
664
+ lang
665
+ version
666
+ notModified
667
+ translations
668
+ }
669
+ }`;
670
+ var REFRESH_LOCALES_MUTATION = `mutation RefreshLocales {
671
+ refreshLocales {
672
+ refreshed
673
+ versions
674
+ }
675
+ }`;
676
+
677
+ // src/modules/locale/index.ts
678
+ var LocaleModule = class {
679
+ #graphql;
680
+ constructor(deps) {
681
+ this.#graphql = deps.graphql;
682
+ }
683
+ /**
684
+ * Fetch translations for a single language.
685
+ *
686
+ * Pass the last-seen `version` as `knownVersion` to opt into not-modified
687
+ * short-circuit semantics: backend returns `{notModified: true, translations: null}`
688
+ * when the cached body still matches, and the caller keeps prior state.
689
+ *
690
+ * Errors surface as TaphubError subclasses with `extensions.code` codes from
691
+ * the backend (e.g. `LangNotSupported`, `InsufficientUpstream`, `FeatureDisabled`).
692
+ * Caller decides the fallback strategy.
693
+ */
694
+ async get(lang, knownVersion, opts) {
695
+ const input = { lang };
696
+ if (knownVersion !== void 0 && knownVersion !== "") {
697
+ input.knownVersion = knownVersion;
698
+ }
699
+ const body = await this.#graphql.request(LOCALES_QUERY, { input }, opts);
700
+ return normaliseLocaleResponse(body.locales);
701
+ }
702
+ /**
703
+ * Trigger an admin refresh — backend re-pulls the source Sheet, invalidates
704
+ * its cache, and writes fresh entries for every supported language.
705
+ *
706
+ * Requires `X-API-Key` header equal to backend `InternalApiKey`. The transport
707
+ * layer is responsible for attaching the header; this method does not handle
708
+ * auth concerns directly.
709
+ */
710
+ async refresh(opts) {
711
+ const body = await this.#graphql.request(
712
+ REFRESH_LOCALES_MUTATION,
713
+ {},
714
+ opts
715
+ );
716
+ return normaliseRefreshLocalesPayload(body.refreshLocales);
717
+ }
718
+ };
719
+
720
+ // src/modules/pair/normalise.ts
721
+ function normalisePair(node) {
569
722
  if (typeof node.id !== "string" || node.id === "" || typeof node.pair !== "string" || node.pair === "" || typeof node.status !== "string" || node.status === "" || !node.config) {
570
723
  throw new TaphubServerError("Invalid response from server", {
571
724
  code: "InvalidResponse"
@@ -624,7 +777,7 @@ function normaliseCandles(list) {
624
777
  coefMults: c.coefMults
625
778
  }));
626
779
  }
627
- function normaliseGamePairInfo(node) {
780
+ function normalisePairInfo(node) {
628
781
  if (typeof node.id !== "string" || node.id === "" || typeof node.pair !== "string" || node.pair === "") {
629
782
  throw new TaphubServerError("Invalid response from server", { code: "InvalidResponse" });
630
783
  }
@@ -634,13 +787,14 @@ function normaliseGamePairInfo(node) {
634
787
  gameplayId: node.gameplayId,
635
788
  gameplayName: node.gameplayName,
636
789
  source: node.source,
637
- gameId: node.gameId ?? null
790
+ // REVIEW[bid-260602]: maps node.agencyPairId (was: node.gameId)
791
+ agencyPairId: node.agencyPairId ?? null
638
792
  };
639
793
  }
640
794
 
641
- // src/modules/game/queries.ts
642
- var GAME_QUERY = `query Game($pair: String!, $gameplaySlug: String) {
643
- game(pair: $pair, gameplaySlug: $gameplaySlug) {
795
+ // src/modules/pair/queries.ts
796
+ var PAIR_QUERY = `query Pair($pair: String!, $gameplaySlug: String) {
797
+ pair(pair: $pair, gameplaySlug: $gameplaySlug) {
644
798
  id pair status created_at
645
799
  config {
646
800
  gridConfig { cellSizeTime cellSizeValue candleSize baseline baselineTime }
@@ -649,8 +803,8 @@ var GAME_QUERY = `query Game($pair: String!, $gameplaySlug: String) {
649
803
  }
650
804
  }
651
805
  }`;
652
- var CHART_HISTORY_QUERY = `query ChartHistory($gameId: ID!, $limit: Int) {
653
- chartHistory(gameId: $gameId, limit: $limit) {
806
+ var CHART_HISTORY_QUERY = `query ChartHistory($agencyPairId: ID!, $limit: Int) {
807
+ chartHistory(agencyPairId: $agencyPairId, limit: $limit) {
654
808
  time o h l c volatility coefMults
655
809
  }
656
810
  }`;
@@ -661,12 +815,12 @@ var BUILDER_AVAILABLE_GAME_PAIRS_QUERY = `query BuilderAvailableGamePairs($gamep
661
815
  gameplayId
662
816
  gameplayName
663
817
  source
664
- gameId
818
+ agencyPairId
665
819
  }
666
820
  }`;
667
821
 
668
- // src/modules/game/index.ts
669
- var GameModule = class {
822
+ // src/modules/pair/index.ts
823
+ var PairModule = class {
670
824
  #graphql;
671
825
  constructor(deps) {
672
826
  this.#graphql = deps.graphql;
@@ -676,7 +830,7 @@ var GameModule = class {
676
830
  if (opts?.gameplaySlug) variables.gameplaySlug = opts.gameplaySlug;
677
831
  let body;
678
832
  try {
679
- body = await this.#graphql.request(GAME_QUERY, variables, opts);
833
+ body = await this.#graphql.request(PAIR_QUERY, variables, opts);
680
834
  } catch (err) {
681
835
  if (err instanceof TaphubValidationError && err.code === "NotExist") {
682
836
  throw new TaphubValidationError("Game not found for pair", {
@@ -686,13 +840,13 @@ var GameModule = class {
686
840
  }
687
841
  throw err;
688
842
  }
689
- if (body.game === null) {
843
+ if (body.pair === null) {
690
844
  throw new TaphubValidationError("Game not found for pair", {
691
845
  code: "GameNotFound",
692
846
  details: { pair }
693
847
  });
694
848
  }
695
- return normaliseGame(body.game);
849
+ return normalisePair(body.pair);
696
850
  }
697
851
  /**
698
852
  * Returns available game pairs, optionally filtered by gameplay.
@@ -701,9 +855,9 @@ var GameModule = class {
701
855
  * `gameId` — use it directly as the MQTT topic `game/{gameId}/candle`.
702
856
  *
703
857
  * @example
704
- * const pairs = await client.game.availableGamePairs({ gameplayId: 'taptrading' });
705
- * const game = await client.game.get(pairs[0].pair, { gameplaySlug: pairs[0].gameplayId });
706
- * const ch = client.realtime?.subscribe(pairs[0].gameId ?? game.id, userId);
858
+ * const pairs = await client.pair.availableGamePairs({ gameplayId: 'taptrading' });
859
+ * const game = await client.pair.get(pairs[0].pair, { gameplaySlug: pairs[0].gameplayId });
860
+ * const ch = client.realtime?.subscribe(pairs[0].agencyPairId ?? game.id, userId);
707
861
  */
708
862
  async availableGamePairs(opts) {
709
863
  const variables = {};
@@ -713,10 +867,11 @@ var GameModule = class {
713
867
  variables,
714
868
  opts
715
869
  );
716
- return body.builderAvailableGamePairs.map(normaliseGamePairInfo);
870
+ return body.builderAvailableGamePairs.map(normalisePairInfo);
717
871
  }
718
- async chartHistory(gameId, limit, opts) {
719
- const variables = { gameId };
872
+ // REVIEW[bid-260602]: chartHistory param/variable renamed agencyPairId (was: gameId)
873
+ async chartHistory(agencyPairId, limit, opts) {
874
+ const variables = { agencyPairId };
720
875
  if (limit !== void 0) {
721
876
  variables.limit = limit;
722
877
  }
@@ -729,149 +884,6 @@ var GameModule = class {
729
884
  }
730
885
  };
731
886
 
732
- // src/modules/leaderboard/normalise.ts
733
- function normaliseLeaderboard(rows) {
734
- if (!Array.isArray(rows)) {
735
- throw new TaphubServerError("Invalid response from server", {
736
- code: "InvalidResponse"
737
- });
738
- }
739
- return rows.map((row) => ({
740
- userId: row.user_id,
741
- username: row.username,
742
- rank: row.rank,
743
- totalBids: row.total_bids,
744
- totalWins: row.total_wins,
745
- totalWagered: row.total_wagered,
746
- totalPayout: row.total_payout,
747
- gain: row.gain
748
- }));
749
- }
750
-
751
- // src/modules/leaderboard/queries.ts
752
- var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
753
- leaderboard(period: $period, sort_by: $sort_by) {
754
- user_id username rank total_bids total_wins total_wagered total_payout gain
755
- }
756
- }`;
757
-
758
- // src/modules/leaderboard/index.ts
759
- var LeaderboardModule = class {
760
- #graphql;
761
- constructor(deps) {
762
- this.#graphql = deps.graphql;
763
- }
764
- async list(args) {
765
- const body = await this.#graphql.request(
766
- LEADERBOARD_QUERY,
767
- { period: args.period, sort_by: args.sortBy },
768
- args.signal ? { signal: args.signal } : void 0
769
- );
770
- return normaliseLeaderboard(body.leaderboard);
771
- }
772
- };
773
-
774
- // src/modules/locale/normalise.ts
775
- function normaliseLocaleResponse(node) {
776
- let translations = null;
777
- if (node.translations !== null) {
778
- try {
779
- translations = JSON.parse(node.translations);
780
- } catch (err) {
781
- throw new TaphubValidationError("Malformed translations JSON string from backend", {
782
- code: "InvalidLocaleResponse",
783
- details: {
784
- lang: node.lang,
785
- version: node.version,
786
- parseError: err instanceof Error ? err.message : String(err)
787
- }
788
- });
789
- }
790
- }
791
- return {
792
- lang: node.lang,
793
- version: node.version,
794
- notModified: node.notModified,
795
- translations
796
- };
797
- }
798
- function normaliseRefreshLocalesPayload(node) {
799
- let versions;
800
- try {
801
- versions = JSON.parse(node.versions);
802
- } catch (err) {
803
- throw new TaphubValidationError("Malformed versions JSON string from backend", {
804
- code: "InvalidRefreshLocalesPayload",
805
- details: {
806
- parseError: err instanceof Error ? err.message : String(err)
807
- }
808
- });
809
- }
810
- return {
811
- refreshed: node.refreshed,
812
- versions
813
- };
814
- }
815
-
816
- // src/modules/locale/queries.ts
817
- var LOCALES_QUERY = `query Locales($input: LocalesInput!) {
818
- locales(input: $input) {
819
- lang
820
- version
821
- notModified
822
- translations
823
- }
824
- }`;
825
- var REFRESH_LOCALES_MUTATION = `mutation RefreshLocales {
826
- refreshLocales {
827
- refreshed
828
- versions
829
- }
830
- }`;
831
-
832
- // src/modules/locale/index.ts
833
- var LocaleModule = class {
834
- #graphql;
835
- constructor(deps) {
836
- this.#graphql = deps.graphql;
837
- }
838
- /**
839
- * Fetch translations for a single language.
840
- *
841
- * Pass the last-seen `version` as `knownVersion` to opt into not-modified
842
- * short-circuit semantics: backend returns `{notModified: true, translations: null}`
843
- * when the cached body still matches, and the caller keeps prior state.
844
- *
845
- * Errors surface as TaphubError subclasses with `extensions.code` codes from
846
- * the backend (e.g. `LangNotSupported`, `InsufficientUpstream`, `FeatureDisabled`).
847
- * Caller decides the fallback strategy.
848
- */
849
- async get(lang, knownVersion, opts) {
850
- const input = { lang };
851
- if (knownVersion !== void 0 && knownVersion !== "") {
852
- input.knownVersion = knownVersion;
853
- }
854
- const body = await this.#graphql.request(LOCALES_QUERY, { input }, opts);
855
- return normaliseLocaleResponse(body.locales);
856
- }
857
- /**
858
- * Trigger an admin refresh — backend re-pulls the source Sheet, invalidates
859
- * its cache, and writes fresh entries for every supported language.
860
- *
861
- * Requires `X-API-Key` header equal to backend `InternalApiKey`. The transport
862
- * layer is responsible for attaching the header; this method does not handle
863
- * auth concerns directly.
864
- */
865
- async refresh(opts) {
866
- const body = await this.#graphql.request(
867
- REFRESH_LOCALES_MUTATION,
868
- {},
869
- opts
870
- );
871
- return normaliseRefreshLocalesPayload(body.refreshLocales);
872
- }
873
- };
874
-
875
887
  // src/transport/mqtt/index.ts
876
888
  var import_mqtt = __toESM(require("mqtt"));
877
889
 
@@ -2526,8 +2538,9 @@ var TaphubClient = class {
2526
2538
  user;
2527
2539
  /** @readonly Auth module — reassignment has no effect at runtime. */
2528
2540
  auth;
2529
- /** @readonly Game module — reassignment has no effect at runtime. */
2530
- game;
2541
+ /** @readonly Pair module — reassignment has no effect at runtime. */
2542
+ // REVIEW[bid-260602]: field pair: PairModule (was: game: GameModule)
2543
+ pair;
2531
2544
  /** @readonly Bid module — reassignment has no effect at runtime. */
2532
2545
  bid;
2533
2546
  /** @readonly Leaderboard module — reassignment has no effect at runtime. */
@@ -2611,7 +2624,7 @@ var TaphubClient = class {
2611
2624
  this.user.clearCurrencies();
2612
2625
  }
2613
2626
  });
2614
- this.game = new GameModule({ graphql: this.#graphql });
2627
+ this.pair = new PairModule({ graphql: this.#graphql });
2615
2628
  this.bid = new BidModule({ graphql: this.#graphql });
2616
2629
  this.leaderboard = new LeaderboardModule({ graphql: this.#graphql });
2617
2630
  this.agencyPairs = new AgencyPairModule({ graphql: this.#graphql });
@@ -2634,8 +2647,8 @@ var TaphubClient = class {
2634
2647
  enumerable: true,
2635
2648
  configurable: false
2636
2649
  });
2637
- Object.defineProperty(this, "game", {
2638
- value: this.game,
2650
+ Object.defineProperty(this, "pair", {
2651
+ value: this.pair,
2639
2652
  writable: false,
2640
2653
  enumerable: true,
2641
2654
  configurable: false
@@ -2797,10 +2810,10 @@ function calculateProbWin_v2(time1, time2, _price1, price2, creationTime, curren
2797
2810
  AgencyPairModule,
2798
2811
  AuthModule,
2799
2812
  BidModule,
2800
- GameModule,
2801
2813
  LeaderboardModule,
2802
2814
  LocaleModule,
2803
2815
  NetworkQualityMonitor,
2816
+ PairModule,
2804
2817
  RealtimeModule,
2805
2818
  TaphubAuthError,
2806
2819
  TaphubClient,