@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.js CHANGED
@@ -366,6 +366,15 @@ function coerceStatus(raw) {
366
366
  console.warn(`Unknown bid status "${raw}", defaulting to "pending"`);
367
367
  return "pending";
368
368
  }
369
+ var SDK_TO_WIRE_STATUS = {
370
+ pending: "pending",
371
+ win: "won",
372
+ lose: "lost",
373
+ cancelled: "cancelled"
374
+ };
375
+ function toWireStatus(status) {
376
+ return SDK_TO_WIRE_STATUS[status];
377
+ }
369
378
  function normaliseBid(node) {
370
379
  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 === "") {
371
380
  throw new TaphubServerError("Invalid response from server", {
@@ -404,8 +413,8 @@ var PLACE_BID_MUTATION = `mutation PlaceBid($input: PlaceBidInput!) {
404
413
  id user_id game_id currency amount coefficient time1 time2 price1 price2 status payout slippage created_at
405
414
  }
406
415
  }`;
407
- var MY_BIDS_QUERY = `query MyBids($status: String, $limit: Int, $offset: Int, $gameId: ID) {
408
- myBids(status: $status, limit: $limit, offset: $offset, gameId: $gameId) {
416
+ var MY_BIDS_QUERY = `query MyBids($statuses: [BidStatus!], $limit: Int, $offset: Int, $gameId: ID) {
417
+ myBids(statuses: $statuses, limit: $limit, offset: $offset, gameId: $gameId) {
409
418
  id user_id game_id currency amount coefficient time1 time2 price1 price2 status payout slippage created_at
410
419
  }
411
420
  }`;
@@ -478,8 +487,9 @@ var BidModule = class {
478
487
  }
479
488
  async listBids(opts) {
480
489
  const variables = {};
481
- if (opts?.status !== void 0) {
482
- variables.status = opts.status;
490
+ const statusList = opts?.statuses ?? (opts?.status !== void 0 ? [opts.status] : void 0);
491
+ if (statusList !== void 0 && statusList.length > 0) {
492
+ variables.statuses = statusList.map(toWireStatus);
483
493
  }
484
494
  if (opts?.limit !== void 0) {
485
495
  variables.limit = opts.limit;
@@ -499,8 +509,151 @@ var BidModule = class {
499
509
  }
500
510
  };
501
511
 
502
- // src/modules/game/normalise.ts
503
- function normaliseGame(node) {
512
+ // src/modules/leaderboard/normalise.ts
513
+ function normaliseLeaderboard(rows) {
514
+ if (!Array.isArray(rows)) {
515
+ throw new TaphubServerError("Invalid response from server", {
516
+ code: "InvalidResponse"
517
+ });
518
+ }
519
+ return rows.map((row) => ({
520
+ userId: row.user_id,
521
+ username: row.username,
522
+ rank: row.rank,
523
+ totalBids: row.total_bids,
524
+ totalWins: row.total_wins,
525
+ totalWagered: row.total_wagered,
526
+ totalPayout: row.total_payout,
527
+ gain: row.gain
528
+ }));
529
+ }
530
+
531
+ // src/modules/leaderboard/queries.ts
532
+ var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
533
+ leaderboard(period: $period, sort_by: $sort_by) {
534
+ user_id username rank total_bids total_wins total_wagered total_payout gain
535
+ }
536
+ }`;
537
+
538
+ // src/modules/leaderboard/index.ts
539
+ var LeaderboardModule = class {
540
+ #graphql;
541
+ constructor(deps) {
542
+ this.#graphql = deps.graphql;
543
+ }
544
+ async list(args) {
545
+ const body = await this.#graphql.request(
546
+ LEADERBOARD_QUERY,
547
+ { period: args.period, sort_by: args.sortBy },
548
+ args.signal ? { signal: args.signal } : void 0
549
+ );
550
+ return normaliseLeaderboard(body.leaderboard);
551
+ }
552
+ };
553
+
554
+ // src/modules/locale/normalise.ts
555
+ function normaliseLocaleResponse(node) {
556
+ let translations = null;
557
+ if (node.translations !== null) {
558
+ try {
559
+ translations = JSON.parse(node.translations);
560
+ } catch (err) {
561
+ throw new TaphubValidationError("Malformed translations JSON string from backend", {
562
+ code: "InvalidLocaleResponse",
563
+ details: {
564
+ lang: node.lang,
565
+ version: node.version,
566
+ parseError: err instanceof Error ? err.message : String(err)
567
+ }
568
+ });
569
+ }
570
+ }
571
+ return {
572
+ lang: node.lang,
573
+ version: node.version,
574
+ notModified: node.notModified,
575
+ translations
576
+ };
577
+ }
578
+ function normaliseRefreshLocalesPayload(node) {
579
+ let versions;
580
+ try {
581
+ versions = JSON.parse(node.versions);
582
+ } catch (err) {
583
+ throw new TaphubValidationError("Malformed versions JSON string from backend", {
584
+ code: "InvalidRefreshLocalesPayload",
585
+ details: {
586
+ parseError: err instanceof Error ? err.message : String(err)
587
+ }
588
+ });
589
+ }
590
+ return {
591
+ refreshed: node.refreshed,
592
+ versions
593
+ };
594
+ }
595
+
596
+ // src/modules/locale/queries.ts
597
+ var LOCALES_QUERY = `query Locales($input: LocalesInput!) {
598
+ locales(input: $input) {
599
+ lang
600
+ version
601
+ notModified
602
+ translations
603
+ }
604
+ }`;
605
+ var REFRESH_LOCALES_MUTATION = `mutation RefreshLocales {
606
+ refreshLocales {
607
+ refreshed
608
+ versions
609
+ }
610
+ }`;
611
+
612
+ // src/modules/locale/index.ts
613
+ var LocaleModule = class {
614
+ #graphql;
615
+ constructor(deps) {
616
+ this.#graphql = deps.graphql;
617
+ }
618
+ /**
619
+ * Fetch translations for a single language.
620
+ *
621
+ * Pass the last-seen `version` as `knownVersion` to opt into not-modified
622
+ * short-circuit semantics: backend returns `{notModified: true, translations: null}`
623
+ * when the cached body still matches, and the caller keeps prior state.
624
+ *
625
+ * Errors surface as TaphubError subclasses with `extensions.code` codes from
626
+ * the backend (e.g. `LangNotSupported`, `InsufficientUpstream`, `FeatureDisabled`).
627
+ * Caller decides the fallback strategy.
628
+ */
629
+ async get(lang, knownVersion, opts) {
630
+ const input = { lang };
631
+ if (knownVersion !== void 0 && knownVersion !== "") {
632
+ input.knownVersion = knownVersion;
633
+ }
634
+ const body = await this.#graphql.request(LOCALES_QUERY, { input }, opts);
635
+ return normaliseLocaleResponse(body.locales);
636
+ }
637
+ /**
638
+ * Trigger an admin refresh — backend re-pulls the source Sheet, invalidates
639
+ * its cache, and writes fresh entries for every supported language.
640
+ *
641
+ * Requires `X-API-Key` header equal to backend `InternalApiKey`. The transport
642
+ * layer is responsible for attaching the header; this method does not handle
643
+ * auth concerns directly.
644
+ */
645
+ async refresh(opts) {
646
+ const body = await this.#graphql.request(
647
+ REFRESH_LOCALES_MUTATION,
648
+ {},
649
+ opts
650
+ );
651
+ return normaliseRefreshLocalesPayload(body.refreshLocales);
652
+ }
653
+ };
654
+
655
+ // src/modules/pair/normalise.ts
656
+ function normalisePair(node) {
504
657
  if (typeof node.id !== "string" || node.id === "" || typeof node.pair !== "string" || node.pair === "" || typeof node.status !== "string" || node.status === "" || !node.config) {
505
658
  throw new TaphubServerError("Invalid response from server", {
506
659
  code: "InvalidResponse"
@@ -559,7 +712,7 @@ function normaliseCandles(list) {
559
712
  coefMults: c.coefMults
560
713
  }));
561
714
  }
562
- function normaliseGamePairInfo(node) {
715
+ function normalisePairInfo(node) {
563
716
  if (typeof node.id !== "string" || node.id === "" || typeof node.pair !== "string" || node.pair === "") {
564
717
  throw new TaphubServerError("Invalid response from server", { code: "InvalidResponse" });
565
718
  }
@@ -569,13 +722,14 @@ function normaliseGamePairInfo(node) {
569
722
  gameplayId: node.gameplayId,
570
723
  gameplayName: node.gameplayName,
571
724
  source: node.source,
572
- gameId: node.gameId ?? null
725
+ // REVIEW[bid-260602]: maps node.agencyPairId (was: node.gameId)
726
+ agencyPairId: node.agencyPairId ?? null
573
727
  };
574
728
  }
575
729
 
576
- // src/modules/game/queries.ts
577
- var GAME_QUERY = `query Game($pair: String!, $gameplaySlug: String) {
578
- game(pair: $pair, gameplaySlug: $gameplaySlug) {
730
+ // src/modules/pair/queries.ts
731
+ var PAIR_QUERY = `query Pair($pair: String!, $gameplaySlug: String) {
732
+ pair(pair: $pair, gameplaySlug: $gameplaySlug) {
579
733
  id pair status created_at
580
734
  config {
581
735
  gridConfig { cellSizeTime cellSizeValue candleSize baseline baselineTime }
@@ -584,8 +738,8 @@ var GAME_QUERY = `query Game($pair: String!, $gameplaySlug: String) {
584
738
  }
585
739
  }
586
740
  }`;
587
- var CHART_HISTORY_QUERY = `query ChartHistory($gameId: ID!, $limit: Int) {
588
- chartHistory(gameId: $gameId, limit: $limit) {
741
+ var CHART_HISTORY_QUERY = `query ChartHistory($agencyPairId: ID!, $limit: Int) {
742
+ chartHistory(agencyPairId: $agencyPairId, limit: $limit) {
589
743
  time o h l c volatility coefMults
590
744
  }
591
745
  }`;
@@ -596,12 +750,12 @@ var BUILDER_AVAILABLE_GAME_PAIRS_QUERY = `query BuilderAvailableGamePairs($gamep
596
750
  gameplayId
597
751
  gameplayName
598
752
  source
599
- gameId
753
+ agencyPairId
600
754
  }
601
755
  }`;
602
756
 
603
- // src/modules/game/index.ts
604
- var GameModule = class {
757
+ // src/modules/pair/index.ts
758
+ var PairModule = class {
605
759
  #graphql;
606
760
  constructor(deps) {
607
761
  this.#graphql = deps.graphql;
@@ -611,7 +765,7 @@ var GameModule = class {
611
765
  if (opts?.gameplaySlug) variables.gameplaySlug = opts.gameplaySlug;
612
766
  let body;
613
767
  try {
614
- body = await this.#graphql.request(GAME_QUERY, variables, opts);
768
+ body = await this.#graphql.request(PAIR_QUERY, variables, opts);
615
769
  } catch (err) {
616
770
  if (err instanceof TaphubValidationError && err.code === "NotExist") {
617
771
  throw new TaphubValidationError("Game not found for pair", {
@@ -621,13 +775,13 @@ var GameModule = class {
621
775
  }
622
776
  throw err;
623
777
  }
624
- if (body.game === null) {
778
+ if (body.pair === null) {
625
779
  throw new TaphubValidationError("Game not found for pair", {
626
780
  code: "GameNotFound",
627
781
  details: { pair }
628
782
  });
629
783
  }
630
- return normaliseGame(body.game);
784
+ return normalisePair(body.pair);
631
785
  }
632
786
  /**
633
787
  * Returns available game pairs, optionally filtered by gameplay.
@@ -636,9 +790,9 @@ var GameModule = class {
636
790
  * `gameId` — use it directly as the MQTT topic `game/{gameId}/candle`.
637
791
  *
638
792
  * @example
639
- * const pairs = await client.game.availableGamePairs({ gameplayId: 'taptrading' });
640
- * const game = await client.game.get(pairs[0].pair, { gameplaySlug: pairs[0].gameplayId });
641
- * const ch = client.realtime?.subscribe(pairs[0].gameId ?? game.id, userId);
793
+ * const pairs = await client.pair.availableGamePairs({ gameplayId: 'taptrading' });
794
+ * const game = await client.pair.get(pairs[0].pair, { gameplaySlug: pairs[0].gameplayId });
795
+ * const ch = client.realtime?.subscribe(pairs[0].agencyPairId ?? game.id, userId);
642
796
  */
643
797
  async availableGamePairs(opts) {
644
798
  const variables = {};
@@ -648,10 +802,11 @@ var GameModule = class {
648
802
  variables,
649
803
  opts
650
804
  );
651
- return body.builderAvailableGamePairs.map(normaliseGamePairInfo);
805
+ return body.builderAvailableGamePairs.map(normalisePairInfo);
652
806
  }
653
- async chartHistory(gameId, limit, opts) {
654
- const variables = { gameId };
807
+ // REVIEW[bid-260602]: chartHistory param/variable renamed agencyPairId (was: gameId)
808
+ async chartHistory(agencyPairId, limit, opts) {
809
+ const variables = { agencyPairId };
655
810
  if (limit !== void 0) {
656
811
  variables.limit = limit;
657
812
  }
@@ -664,149 +819,6 @@ var GameModule = class {
664
819
  }
665
820
  };
666
821
 
667
- // src/modules/leaderboard/normalise.ts
668
- function normaliseLeaderboard(rows) {
669
- if (!Array.isArray(rows)) {
670
- throw new TaphubServerError("Invalid response from server", {
671
- code: "InvalidResponse"
672
- });
673
- }
674
- return rows.map((row) => ({
675
- userId: row.user_id,
676
- username: row.username,
677
- rank: row.rank,
678
- totalBids: row.total_bids,
679
- totalWins: row.total_wins,
680
- totalWagered: row.total_wagered,
681
- totalPayout: row.total_payout,
682
- gain: row.gain
683
- }));
684
- }
685
-
686
- // src/modules/leaderboard/queries.ts
687
- var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
688
- leaderboard(period: $period, sort_by: $sort_by) {
689
- user_id username rank total_bids total_wins total_wagered total_payout gain
690
- }
691
- }`;
692
-
693
- // src/modules/leaderboard/index.ts
694
- var LeaderboardModule = class {
695
- #graphql;
696
- constructor(deps) {
697
- this.#graphql = deps.graphql;
698
- }
699
- async list(args) {
700
- const body = await this.#graphql.request(
701
- LEADERBOARD_QUERY,
702
- { period: args.period, sort_by: args.sortBy },
703
- args.signal ? { signal: args.signal } : void 0
704
- );
705
- return normaliseLeaderboard(body.leaderboard);
706
- }
707
- };
708
-
709
- // src/modules/locale/normalise.ts
710
- function normaliseLocaleResponse(node) {
711
- let translations = null;
712
- if (node.translations !== null) {
713
- try {
714
- translations = JSON.parse(node.translations);
715
- } catch (err) {
716
- throw new TaphubValidationError("Malformed translations JSON string from backend", {
717
- code: "InvalidLocaleResponse",
718
- details: {
719
- lang: node.lang,
720
- version: node.version,
721
- parseError: err instanceof Error ? err.message : String(err)
722
- }
723
- });
724
- }
725
- }
726
- return {
727
- lang: node.lang,
728
- version: node.version,
729
- notModified: node.notModified,
730
- translations
731
- };
732
- }
733
- function normaliseRefreshLocalesPayload(node) {
734
- let versions;
735
- try {
736
- versions = JSON.parse(node.versions);
737
- } catch (err) {
738
- throw new TaphubValidationError("Malformed versions JSON string from backend", {
739
- code: "InvalidRefreshLocalesPayload",
740
- details: {
741
- parseError: err instanceof Error ? err.message : String(err)
742
- }
743
- });
744
- }
745
- return {
746
- refreshed: node.refreshed,
747
- versions
748
- };
749
- }
750
-
751
- // src/modules/locale/queries.ts
752
- var LOCALES_QUERY = `query Locales($input: LocalesInput!) {
753
- locales(input: $input) {
754
- lang
755
- version
756
- notModified
757
- translations
758
- }
759
- }`;
760
- var REFRESH_LOCALES_MUTATION = `mutation RefreshLocales {
761
- refreshLocales {
762
- refreshed
763
- versions
764
- }
765
- }`;
766
-
767
- // src/modules/locale/index.ts
768
- var LocaleModule = class {
769
- #graphql;
770
- constructor(deps) {
771
- this.#graphql = deps.graphql;
772
- }
773
- /**
774
- * Fetch translations for a single language.
775
- *
776
- * Pass the last-seen `version` as `knownVersion` to opt into not-modified
777
- * short-circuit semantics: backend returns `{notModified: true, translations: null}`
778
- * when the cached body still matches, and the caller keeps prior state.
779
- *
780
- * Errors surface as TaphubError subclasses with `extensions.code` codes from
781
- * the backend (e.g. `LangNotSupported`, `InsufficientUpstream`, `FeatureDisabled`).
782
- * Caller decides the fallback strategy.
783
- */
784
- async get(lang, knownVersion, opts) {
785
- const input = { lang };
786
- if (knownVersion !== void 0 && knownVersion !== "") {
787
- input.knownVersion = knownVersion;
788
- }
789
- const body = await this.#graphql.request(LOCALES_QUERY, { input }, opts);
790
- return normaliseLocaleResponse(body.locales);
791
- }
792
- /**
793
- * Trigger an admin refresh — backend re-pulls the source Sheet, invalidates
794
- * its cache, and writes fresh entries for every supported language.
795
- *
796
- * Requires `X-API-Key` header equal to backend `InternalApiKey`. The transport
797
- * layer is responsible for attaching the header; this method does not handle
798
- * auth concerns directly.
799
- */
800
- async refresh(opts) {
801
- const body = await this.#graphql.request(
802
- REFRESH_LOCALES_MUTATION,
803
- {},
804
- opts
805
- );
806
- return normaliseRefreshLocalesPayload(body.refreshLocales);
807
- }
808
- };
809
-
810
822
  // src/transport/mqtt/index.ts
811
823
  import mqtt from "mqtt";
812
824
 
@@ -2461,8 +2473,9 @@ var TaphubClient = class {
2461
2473
  user;
2462
2474
  /** @readonly Auth module — reassignment has no effect at runtime. */
2463
2475
  auth;
2464
- /** @readonly Game module — reassignment has no effect at runtime. */
2465
- game;
2476
+ /** @readonly Pair module — reassignment has no effect at runtime. */
2477
+ // REVIEW[bid-260602]: field pair: PairModule (was: game: GameModule)
2478
+ pair;
2466
2479
  /** @readonly Bid module — reassignment has no effect at runtime. */
2467
2480
  bid;
2468
2481
  /** @readonly Leaderboard module — reassignment has no effect at runtime. */
@@ -2546,7 +2559,7 @@ var TaphubClient = class {
2546
2559
  this.user.clearCurrencies();
2547
2560
  }
2548
2561
  });
2549
- this.game = new GameModule({ graphql: this.#graphql });
2562
+ this.pair = new PairModule({ graphql: this.#graphql });
2550
2563
  this.bid = new BidModule({ graphql: this.#graphql });
2551
2564
  this.leaderboard = new LeaderboardModule({ graphql: this.#graphql });
2552
2565
  this.agencyPairs = new AgencyPairModule({ graphql: this.#graphql });
@@ -2569,8 +2582,8 @@ var TaphubClient = class {
2569
2582
  enumerable: true,
2570
2583
  configurable: false
2571
2584
  });
2572
- Object.defineProperty(this, "game", {
2573
- value: this.game,
2585
+ Object.defineProperty(this, "pair", {
2586
+ value: this.pair,
2574
2587
  writable: false,
2575
2588
  enumerable: true,
2576
2589
  configurable: false
@@ -2731,10 +2744,10 @@ export {
2731
2744
  AgencyPairModule,
2732
2745
  AuthModule,
2733
2746
  BidModule,
2734
- GameModule,
2735
2747
  LeaderboardModule,
2736
2748
  LocaleModule,
2737
2749
  NetworkQualityMonitor,
2750
+ PairModule,
2738
2751
  RealtimeModule,
2739
2752
  TaphubAuthError,
2740
2753
  TaphubClient,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taphubhq/sdk-core",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "Core SDK for building on the TabHub platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",