@taphubhq/sdk-core 0.20.0 → 0.21.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 +106 -0
- package/dist/index.d.mts +102 -1
- package/dist/index.d.ts +102 -1
- package/dist/index.js +106 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -608,6 +608,41 @@ function normaliseLeaderboard(rows) {
|
|
|
608
608
|
gain: row.gain
|
|
609
609
|
}));
|
|
610
610
|
}
|
|
611
|
+
function normaliseRankEntry(row) {
|
|
612
|
+
return {
|
|
613
|
+
userId: row.userId,
|
|
614
|
+
loginBy: row.loginBy,
|
|
615
|
+
username: row.username,
|
|
616
|
+
rank: row.rank,
|
|
617
|
+
pnl: row.pnl,
|
|
618
|
+
vol: row.vol,
|
|
619
|
+
payout: row.payout,
|
|
620
|
+
wins: row.wins,
|
|
621
|
+
bids: row.bids
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
function normaliseRankBoard(wire) {
|
|
625
|
+
if (wire == null || typeof wire !== "object") {
|
|
626
|
+
throw new TaphubServerError("Invalid response from server", {
|
|
627
|
+
code: "InvalidResponse"
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
return {
|
|
631
|
+
period: wire.period,
|
|
632
|
+
range: { from: wire.range?.from, to: wire.range?.to },
|
|
633
|
+
sort: wire.sort,
|
|
634
|
+
sortDir: wire.sortDir,
|
|
635
|
+
total: wire.total,
|
|
636
|
+
entries: Array.isArray(wire.entries) ? wire.entries.map(normaliseRankEntry) : []
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function normaliseRankMe(wire) {
|
|
640
|
+
return {
|
|
641
|
+
rank: wire.rank,
|
|
642
|
+
total: wire.total,
|
|
643
|
+
entry: wire.entry ? normaliseRankEntry(wire.entry) : null
|
|
644
|
+
};
|
|
645
|
+
}
|
|
611
646
|
|
|
612
647
|
// src/modules/leaderboard/queries.ts
|
|
613
648
|
var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
|
|
@@ -615,6 +650,23 @@ var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!)
|
|
|
615
650
|
user_id username rank total_bids total_wins total_wagered total_payout gain
|
|
616
651
|
}
|
|
617
652
|
}`;
|
|
653
|
+
var RANK_LEADERBOARD_V2_QUERY = `query RankLeaderboardV2($input: RankBoardInput!) {
|
|
654
|
+
rank_leaderboardV2(input: $input) {
|
|
655
|
+
period
|
|
656
|
+
range { from to }
|
|
657
|
+
sort
|
|
658
|
+
sortDir
|
|
659
|
+
total
|
|
660
|
+
entries { userId loginBy username rank pnl vol payout wins bids }
|
|
661
|
+
}
|
|
662
|
+
}`;
|
|
663
|
+
var RANK_ME_QUERY = `query RankMe($input: RankMeInput!) {
|
|
664
|
+
rank_me(input: $input) {
|
|
665
|
+
rank
|
|
666
|
+
total
|
|
667
|
+
entry { userId loginBy username rank pnl vol payout wins bids }
|
|
668
|
+
}
|
|
669
|
+
}`;
|
|
618
670
|
|
|
619
671
|
// src/modules/leaderboard/index.ts
|
|
620
672
|
var LeaderboardModule = class {
|
|
@@ -622,6 +674,11 @@ var LeaderboardModule = class {
|
|
|
622
674
|
constructor(deps) {
|
|
623
675
|
this.#graphql = deps.graphql;
|
|
624
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* @deprecated Use {@link LeaderboardModule.rankBoard}. The backend
|
|
679
|
+
* `leaderboard` query is `@deprecated` in favour of `rank_leaderboardV2`
|
|
680
|
+
* (duration presets, pnl/vol sort, pagination, current-user `me`).
|
|
681
|
+
*/
|
|
625
682
|
async list(args) {
|
|
626
683
|
const body = await this.#graphql.publicRequest(
|
|
627
684
|
LEADERBOARD_QUERY,
|
|
@@ -630,6 +687,55 @@ var LeaderboardModule = class {
|
|
|
630
687
|
);
|
|
631
688
|
return normaliseLeaderboard(body.leaderboard);
|
|
632
689
|
}
|
|
690
|
+
/**
|
|
691
|
+
* Fetch the public duration-scoped rank board (`rank_leaderboardV2`).
|
|
692
|
+
*
|
|
693
|
+
* Supports the fixed period presets plus `custom` (which requires an
|
|
694
|
+
* hour-aligned `range`), `pnl`/`vol` sort with an explicit direction, offset
|
|
695
|
+
* pagination, and a `total` count for "#X of N" UI. Optional args are omitted
|
|
696
|
+
* from the wire `input` when undefined so the server defaults apply
|
|
697
|
+
* (`sort = pnl`, `sortDir = desc`, `limit = 50`, `offset = 0`).
|
|
698
|
+
*
|
|
699
|
+
* bid-260606-leaderboard-split-my-rank: the board is **public and identical for
|
|
700
|
+
* every caller** — it carries no per-user data. For the signed-in caller's own
|
|
701
|
+
* row+rank, use {@link LeaderboardModule.myRank}.
|
|
702
|
+
*/
|
|
703
|
+
async rankBoard(args) {
|
|
704
|
+
const input = { period: args.period };
|
|
705
|
+
if (args.range) input.range = { from: args.range.from, to: args.range.to };
|
|
706
|
+
if (args.sort) input.sort = args.sort;
|
|
707
|
+
if (args.sortDir) input.sortDir = args.sortDir;
|
|
708
|
+
if (args.limit != null || args.offset != null) {
|
|
709
|
+
input.p = { limit: args.limit, offset: args.offset };
|
|
710
|
+
}
|
|
711
|
+
const body = await this.#graphql.publicRequest(
|
|
712
|
+
RANK_LEADERBOARD_V2_QUERY,
|
|
713
|
+
{ input },
|
|
714
|
+
args.signal ? { signal: args.signal } : void 0
|
|
715
|
+
);
|
|
716
|
+
return normaliseRankBoard(body.rank_leaderboardV2);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Fetch the signed-in caller's own row + rank for the same window (`rank_me`) —
|
|
720
|
+
* the per-user companion to {@link LeaderboardModule.rankBoard}.
|
|
721
|
+
*
|
|
722
|
+
* Unlike the board, this attaches the user JWT (`request`, not `publicRequest`)
|
|
723
|
+
* so the backend resolves the caller. Returns `null` when no user is signed in
|
|
724
|
+
* (the backend returns `rank_me: null`). `MyRank.entry` is `null` when the
|
|
725
|
+
* caller has no activity in the window.
|
|
726
|
+
*/
|
|
727
|
+
async myRank(args) {
|
|
728
|
+
const input = { period: args.period };
|
|
729
|
+
if (args.range) input.range = { from: args.range.from, to: args.range.to };
|
|
730
|
+
if (args.sort) input.sort = args.sort;
|
|
731
|
+
if (args.sortDir) input.sortDir = args.sortDir;
|
|
732
|
+
const body = await this.#graphql.request(
|
|
733
|
+
RANK_ME_QUERY,
|
|
734
|
+
{ input },
|
|
735
|
+
args.signal ? { signal: args.signal } : void 0
|
|
736
|
+
);
|
|
737
|
+
return body.rank_me ? normaliseRankMe(body.rank_me) : null;
|
|
738
|
+
}
|
|
633
739
|
};
|
|
634
740
|
|
|
635
741
|
// src/modules/locale/normalise.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -261,7 +261,15 @@ declare class BidModule {
|
|
|
261
261
|
}): Promise<Bid[]>;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* @deprecated Use {@link RankPeriod} with `client.leaderboard.rankBoard`. The
|
|
266
|
+
* v1 `leaderboard` query is `@deprecated` on the backend in favour of
|
|
267
|
+
* `rank_leaderboardV2` (duration presets + current-user rank + pnl/vol).
|
|
268
|
+
*/
|
|
264
269
|
type LeaderboardPeriod = 'weekly' | 'all_time';
|
|
270
|
+
/**
|
|
271
|
+
* @deprecated Use {@link RankSort} with `client.leaderboard.rankBoard`.
|
|
272
|
+
*/
|
|
265
273
|
type LeaderboardSortBy = 'gain' | 'wagered';
|
|
266
274
|
interface LeaderboardEntry {
|
|
267
275
|
userId: string;
|
|
@@ -273,6 +281,48 @@ interface LeaderboardEntry {
|
|
|
273
281
|
totalPayout: string;
|
|
274
282
|
gain: string;
|
|
275
283
|
}
|
|
284
|
+
/** Fixed duration filters. `custom` requires an hour-aligned `range`. */
|
|
285
|
+
type RankPeriod = 'today' | 'yesterday' | 'last_7d' | 'last_30d' | 'all_time' | 'custom';
|
|
286
|
+
/** `pnl` = net profit (payout - vol); `vol` = wagered volume. */
|
|
287
|
+
type RankSort = 'pnl' | 'vol';
|
|
288
|
+
type SortDir = 'asc' | 'desc';
|
|
289
|
+
interface RankEntry {
|
|
290
|
+
userId: string;
|
|
291
|
+
/** Same denormalised value as `username`; dashboard display alias. */
|
|
292
|
+
loginBy: string;
|
|
293
|
+
username: string;
|
|
294
|
+
rank: number;
|
|
295
|
+
/** Net profit = payout - vol (decimal as string). */
|
|
296
|
+
pnl: string;
|
|
297
|
+
/** Total wagered volume (decimal as string). */
|
|
298
|
+
vol: string;
|
|
299
|
+
payout: string;
|
|
300
|
+
wins: number;
|
|
301
|
+
bids: number;
|
|
302
|
+
}
|
|
303
|
+
interface RankBoard {
|
|
304
|
+
period: RankPeriod;
|
|
305
|
+
/** Resolved window (after hour-align) for UI display. */
|
|
306
|
+
range: {
|
|
307
|
+
from: string;
|
|
308
|
+
to: string;
|
|
309
|
+
};
|
|
310
|
+
sort: RankSort;
|
|
311
|
+
sortDir: SortDir;
|
|
312
|
+
/** All active users in the window → "#X of N". */
|
|
313
|
+
total: number;
|
|
314
|
+
entries: RankEntry[];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* The signed-in caller's own row + rank (`rank_me`), split out of {@link RankBoard} so the
|
|
318
|
+
* board stays a pure public/cacheable read. `entry` is `null` when the caller has no activity
|
|
319
|
+
* in the window (`rank` is then 0); `total` is the ranked-pool size for "#rank of total".
|
|
320
|
+
*/
|
|
321
|
+
interface MyRank {
|
|
322
|
+
rank: number;
|
|
323
|
+
entry: RankEntry | null;
|
|
324
|
+
total: number;
|
|
325
|
+
}
|
|
276
326
|
|
|
277
327
|
interface LeaderboardModuleDeps {
|
|
278
328
|
graphql: GraphQLTransport;
|
|
@@ -280,11 +330,62 @@ interface LeaderboardModuleDeps {
|
|
|
280
330
|
declare class LeaderboardModule {
|
|
281
331
|
#private;
|
|
282
332
|
constructor(deps: LeaderboardModuleDeps);
|
|
333
|
+
/**
|
|
334
|
+
* @deprecated Use {@link LeaderboardModule.rankBoard}. The backend
|
|
335
|
+
* `leaderboard` query is `@deprecated` in favour of `rank_leaderboardV2`
|
|
336
|
+
* (duration presets, pnl/vol sort, pagination, current-user `me`).
|
|
337
|
+
*/
|
|
283
338
|
list(args: {
|
|
284
339
|
period: LeaderboardPeriod;
|
|
285
340
|
sortBy: LeaderboardSortBy;
|
|
286
341
|
signal?: AbortSignal;
|
|
287
342
|
}): Promise<LeaderboardEntry[]>;
|
|
343
|
+
/**
|
|
344
|
+
* Fetch the public duration-scoped rank board (`rank_leaderboardV2`).
|
|
345
|
+
*
|
|
346
|
+
* Supports the fixed period presets plus `custom` (which requires an
|
|
347
|
+
* hour-aligned `range`), `pnl`/`vol` sort with an explicit direction, offset
|
|
348
|
+
* pagination, and a `total` count for "#X of N" UI. Optional args are omitted
|
|
349
|
+
* from the wire `input` when undefined so the server defaults apply
|
|
350
|
+
* (`sort = pnl`, `sortDir = desc`, `limit = 50`, `offset = 0`).
|
|
351
|
+
*
|
|
352
|
+
* bid-260606-leaderboard-split-my-rank: the board is **public and identical for
|
|
353
|
+
* every caller** — it carries no per-user data. For the signed-in caller's own
|
|
354
|
+
* row+rank, use {@link LeaderboardModule.myRank}.
|
|
355
|
+
*/
|
|
356
|
+
rankBoard(args: {
|
|
357
|
+
period: RankPeriod;
|
|
358
|
+
/** ISO 8601 UTC, hour-aligned. Required iff `period === 'custom'`. */
|
|
359
|
+
range?: {
|
|
360
|
+
from: string;
|
|
361
|
+
to: string;
|
|
362
|
+
};
|
|
363
|
+
sort?: RankSort;
|
|
364
|
+
sortDir?: SortDir;
|
|
365
|
+
limit?: number;
|
|
366
|
+
offset?: number;
|
|
367
|
+
signal?: AbortSignal;
|
|
368
|
+
}): Promise<RankBoard>;
|
|
369
|
+
/**
|
|
370
|
+
* Fetch the signed-in caller's own row + rank for the same window (`rank_me`) —
|
|
371
|
+
* the per-user companion to {@link LeaderboardModule.rankBoard}.
|
|
372
|
+
*
|
|
373
|
+
* Unlike the board, this attaches the user JWT (`request`, not `publicRequest`)
|
|
374
|
+
* so the backend resolves the caller. Returns `null` when no user is signed in
|
|
375
|
+
* (the backend returns `rank_me: null`). `MyRank.entry` is `null` when the
|
|
376
|
+
* caller has no activity in the window.
|
|
377
|
+
*/
|
|
378
|
+
myRank(args: {
|
|
379
|
+
period: RankPeriod;
|
|
380
|
+
/** ISO 8601 UTC, hour-aligned. Required iff `period === 'custom'`. */
|
|
381
|
+
range?: {
|
|
382
|
+
from: string;
|
|
383
|
+
to: string;
|
|
384
|
+
};
|
|
385
|
+
sort?: RankSort;
|
|
386
|
+
sortDir?: SortDir;
|
|
387
|
+
signal?: AbortSignal;
|
|
388
|
+
}): Promise<MyRank | null>;
|
|
288
389
|
}
|
|
289
390
|
|
|
290
391
|
/**
|
|
@@ -1023,4 +1124,4 @@ declare function adaptiveSimpson(f: (x: number) => number, a: number, b: number,
|
|
|
1023
1124
|
declare function calculateProbWin(time1: number, time2: number, _price1: number, price2: number, creationTime: number, currentPrice: number, volatility: number): number;
|
|
1024
1125
|
declare function calculateProbWin_v2(time1: number, time2: number, _price1: number, price2: number, creationTime: number, currentPrice: number, volatility: number): number;
|
|
1025
1126
|
|
|
1026
|
-
export { type AgencyPairFilter, AgencyPairModule, type AgencyPairStats, type AgencyPairStatus, AuthModule, type BackendHealth, type Bid, BidModule, type BidStatus, type CancelBidResult, type Candle, type Constraints, type Currency, GameChannel, type GameConfig, type GridConfig, type LeaderboardEntry, LeaderboardModule, type LeaderboardPeriod, type LeaderboardSortBy, LocaleModule, type LocaleRefreshResult, type LocaleResponse, type LocaleTranslations, type LoginResult, type Me, type MqttAcceptedBid, type MqttAgencyPairStatsEvent, type MqttBalanceEvent, type MqttBidAcceptedEvent, type MqttBidLostEvent, type MqttBidWonEvent, type MqttCandleEvent, type MqttConfigEvent, type MqttIdealConfigEvent, type MqttWalletBalanceEvent, type NetworkLevel, type NetworkQuality, NetworkQualityMonitor, type Pair, type PairInfo, PairModule, type PlaceBidInput, RealtimeModule, type Sample, type SampleReason, type SignalSource, TaphubAuthError, TaphubClient, type TaphubClientConfig, TaphubError, TaphubEventBus, type TaphubEventMap, TaphubNetworkError, TaphubServerError, TaphubSlippageError, TaphubStorage, type TaphubStorageAdapter, TaphubValidationError, type User, UserModule, type UserPnL, type UserPnLPeriod, type Wallet as UserWallet, type Wallet$1 as Wallet, type WalletBalanceReason, WalletChannel, adaptiveSimpson, autoDetectStorage, calculateProbWin, calculateProbWin_v2, errorFunction, isCancelled, isLoss, isPending, isTerminal, isWin, normalCDF, normalPDF };
|
|
1127
|
+
export { type AgencyPairFilter, AgencyPairModule, type AgencyPairStats, type AgencyPairStatus, AuthModule, type BackendHealth, type Bid, BidModule, type BidStatus, type CancelBidResult, type Candle, type Constraints, type Currency, GameChannel, type GameConfig, type GridConfig, type LeaderboardEntry, LeaderboardModule, type LeaderboardPeriod, type LeaderboardSortBy, LocaleModule, type LocaleRefreshResult, type LocaleResponse, type LocaleTranslations, type LoginResult, type Me, type MqttAcceptedBid, type MqttAgencyPairStatsEvent, type MqttBalanceEvent, type MqttBidAcceptedEvent, type MqttBidLostEvent, type MqttBidWonEvent, type MqttCandleEvent, type MqttConfigEvent, type MqttIdealConfigEvent, type MqttWalletBalanceEvent, type MyRank, type NetworkLevel, type NetworkQuality, NetworkQualityMonitor, type Pair, type PairInfo, PairModule, type PlaceBidInput, type RankBoard, type RankEntry, type RankPeriod, type RankSort, RealtimeModule, type Sample, type SampleReason, type SignalSource, type SortDir, TaphubAuthError, TaphubClient, type TaphubClientConfig, TaphubError, TaphubEventBus, type TaphubEventMap, TaphubNetworkError, TaphubServerError, TaphubSlippageError, TaphubStorage, type TaphubStorageAdapter, TaphubValidationError, type User, UserModule, type UserPnL, type UserPnLPeriod, type Wallet as UserWallet, type Wallet$1 as Wallet, type WalletBalanceReason, WalletChannel, adaptiveSimpson, autoDetectStorage, calculateProbWin, calculateProbWin_v2, errorFunction, isCancelled, isLoss, isPending, isTerminal, isWin, normalCDF, normalPDF };
|
package/dist/index.d.ts
CHANGED
|
@@ -261,7 +261,15 @@ declare class BidModule {
|
|
|
261
261
|
}): Promise<Bid[]>;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* @deprecated Use {@link RankPeriod} with `client.leaderboard.rankBoard`. The
|
|
266
|
+
* v1 `leaderboard` query is `@deprecated` on the backend in favour of
|
|
267
|
+
* `rank_leaderboardV2` (duration presets + current-user rank + pnl/vol).
|
|
268
|
+
*/
|
|
264
269
|
type LeaderboardPeriod = 'weekly' | 'all_time';
|
|
270
|
+
/**
|
|
271
|
+
* @deprecated Use {@link RankSort} with `client.leaderboard.rankBoard`.
|
|
272
|
+
*/
|
|
265
273
|
type LeaderboardSortBy = 'gain' | 'wagered';
|
|
266
274
|
interface LeaderboardEntry {
|
|
267
275
|
userId: string;
|
|
@@ -273,6 +281,48 @@ interface LeaderboardEntry {
|
|
|
273
281
|
totalPayout: string;
|
|
274
282
|
gain: string;
|
|
275
283
|
}
|
|
284
|
+
/** Fixed duration filters. `custom` requires an hour-aligned `range`. */
|
|
285
|
+
type RankPeriod = 'today' | 'yesterday' | 'last_7d' | 'last_30d' | 'all_time' | 'custom';
|
|
286
|
+
/** `pnl` = net profit (payout - vol); `vol` = wagered volume. */
|
|
287
|
+
type RankSort = 'pnl' | 'vol';
|
|
288
|
+
type SortDir = 'asc' | 'desc';
|
|
289
|
+
interface RankEntry {
|
|
290
|
+
userId: string;
|
|
291
|
+
/** Same denormalised value as `username`; dashboard display alias. */
|
|
292
|
+
loginBy: string;
|
|
293
|
+
username: string;
|
|
294
|
+
rank: number;
|
|
295
|
+
/** Net profit = payout - vol (decimal as string). */
|
|
296
|
+
pnl: string;
|
|
297
|
+
/** Total wagered volume (decimal as string). */
|
|
298
|
+
vol: string;
|
|
299
|
+
payout: string;
|
|
300
|
+
wins: number;
|
|
301
|
+
bids: number;
|
|
302
|
+
}
|
|
303
|
+
interface RankBoard {
|
|
304
|
+
period: RankPeriod;
|
|
305
|
+
/** Resolved window (after hour-align) for UI display. */
|
|
306
|
+
range: {
|
|
307
|
+
from: string;
|
|
308
|
+
to: string;
|
|
309
|
+
};
|
|
310
|
+
sort: RankSort;
|
|
311
|
+
sortDir: SortDir;
|
|
312
|
+
/** All active users in the window → "#X of N". */
|
|
313
|
+
total: number;
|
|
314
|
+
entries: RankEntry[];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* The signed-in caller's own row + rank (`rank_me`), split out of {@link RankBoard} so the
|
|
318
|
+
* board stays a pure public/cacheable read. `entry` is `null` when the caller has no activity
|
|
319
|
+
* in the window (`rank` is then 0); `total` is the ranked-pool size for "#rank of total".
|
|
320
|
+
*/
|
|
321
|
+
interface MyRank {
|
|
322
|
+
rank: number;
|
|
323
|
+
entry: RankEntry | null;
|
|
324
|
+
total: number;
|
|
325
|
+
}
|
|
276
326
|
|
|
277
327
|
interface LeaderboardModuleDeps {
|
|
278
328
|
graphql: GraphQLTransport;
|
|
@@ -280,11 +330,62 @@ interface LeaderboardModuleDeps {
|
|
|
280
330
|
declare class LeaderboardModule {
|
|
281
331
|
#private;
|
|
282
332
|
constructor(deps: LeaderboardModuleDeps);
|
|
333
|
+
/**
|
|
334
|
+
* @deprecated Use {@link LeaderboardModule.rankBoard}. The backend
|
|
335
|
+
* `leaderboard` query is `@deprecated` in favour of `rank_leaderboardV2`
|
|
336
|
+
* (duration presets, pnl/vol sort, pagination, current-user `me`).
|
|
337
|
+
*/
|
|
283
338
|
list(args: {
|
|
284
339
|
period: LeaderboardPeriod;
|
|
285
340
|
sortBy: LeaderboardSortBy;
|
|
286
341
|
signal?: AbortSignal;
|
|
287
342
|
}): Promise<LeaderboardEntry[]>;
|
|
343
|
+
/**
|
|
344
|
+
* Fetch the public duration-scoped rank board (`rank_leaderboardV2`).
|
|
345
|
+
*
|
|
346
|
+
* Supports the fixed period presets plus `custom` (which requires an
|
|
347
|
+
* hour-aligned `range`), `pnl`/`vol` sort with an explicit direction, offset
|
|
348
|
+
* pagination, and a `total` count for "#X of N" UI. Optional args are omitted
|
|
349
|
+
* from the wire `input` when undefined so the server defaults apply
|
|
350
|
+
* (`sort = pnl`, `sortDir = desc`, `limit = 50`, `offset = 0`).
|
|
351
|
+
*
|
|
352
|
+
* bid-260606-leaderboard-split-my-rank: the board is **public and identical for
|
|
353
|
+
* every caller** — it carries no per-user data. For the signed-in caller's own
|
|
354
|
+
* row+rank, use {@link LeaderboardModule.myRank}.
|
|
355
|
+
*/
|
|
356
|
+
rankBoard(args: {
|
|
357
|
+
period: RankPeriod;
|
|
358
|
+
/** ISO 8601 UTC, hour-aligned. Required iff `period === 'custom'`. */
|
|
359
|
+
range?: {
|
|
360
|
+
from: string;
|
|
361
|
+
to: string;
|
|
362
|
+
};
|
|
363
|
+
sort?: RankSort;
|
|
364
|
+
sortDir?: SortDir;
|
|
365
|
+
limit?: number;
|
|
366
|
+
offset?: number;
|
|
367
|
+
signal?: AbortSignal;
|
|
368
|
+
}): Promise<RankBoard>;
|
|
369
|
+
/**
|
|
370
|
+
* Fetch the signed-in caller's own row + rank for the same window (`rank_me`) —
|
|
371
|
+
* the per-user companion to {@link LeaderboardModule.rankBoard}.
|
|
372
|
+
*
|
|
373
|
+
* Unlike the board, this attaches the user JWT (`request`, not `publicRequest`)
|
|
374
|
+
* so the backend resolves the caller. Returns `null` when no user is signed in
|
|
375
|
+
* (the backend returns `rank_me: null`). `MyRank.entry` is `null` when the
|
|
376
|
+
* caller has no activity in the window.
|
|
377
|
+
*/
|
|
378
|
+
myRank(args: {
|
|
379
|
+
period: RankPeriod;
|
|
380
|
+
/** ISO 8601 UTC, hour-aligned. Required iff `period === 'custom'`. */
|
|
381
|
+
range?: {
|
|
382
|
+
from: string;
|
|
383
|
+
to: string;
|
|
384
|
+
};
|
|
385
|
+
sort?: RankSort;
|
|
386
|
+
sortDir?: SortDir;
|
|
387
|
+
signal?: AbortSignal;
|
|
388
|
+
}): Promise<MyRank | null>;
|
|
288
389
|
}
|
|
289
390
|
|
|
290
391
|
/**
|
|
@@ -1023,4 +1124,4 @@ declare function adaptiveSimpson(f: (x: number) => number, a: number, b: number,
|
|
|
1023
1124
|
declare function calculateProbWin(time1: number, time2: number, _price1: number, price2: number, creationTime: number, currentPrice: number, volatility: number): number;
|
|
1024
1125
|
declare function calculateProbWin_v2(time1: number, time2: number, _price1: number, price2: number, creationTime: number, currentPrice: number, volatility: number): number;
|
|
1025
1126
|
|
|
1026
|
-
export { type AgencyPairFilter, AgencyPairModule, type AgencyPairStats, type AgencyPairStatus, AuthModule, type BackendHealth, type Bid, BidModule, type BidStatus, type CancelBidResult, type Candle, type Constraints, type Currency, GameChannel, type GameConfig, type GridConfig, type LeaderboardEntry, LeaderboardModule, type LeaderboardPeriod, type LeaderboardSortBy, LocaleModule, type LocaleRefreshResult, type LocaleResponse, type LocaleTranslations, type LoginResult, type Me, type MqttAcceptedBid, type MqttAgencyPairStatsEvent, type MqttBalanceEvent, type MqttBidAcceptedEvent, type MqttBidLostEvent, type MqttBidWonEvent, type MqttCandleEvent, type MqttConfigEvent, type MqttIdealConfigEvent, type MqttWalletBalanceEvent, type NetworkLevel, type NetworkQuality, NetworkQualityMonitor, type Pair, type PairInfo, PairModule, type PlaceBidInput, RealtimeModule, type Sample, type SampleReason, type SignalSource, TaphubAuthError, TaphubClient, type TaphubClientConfig, TaphubError, TaphubEventBus, type TaphubEventMap, TaphubNetworkError, TaphubServerError, TaphubSlippageError, TaphubStorage, type TaphubStorageAdapter, TaphubValidationError, type User, UserModule, type UserPnL, type UserPnLPeriod, type Wallet as UserWallet, type Wallet$1 as Wallet, type WalletBalanceReason, WalletChannel, adaptiveSimpson, autoDetectStorage, calculateProbWin, calculateProbWin_v2, errorFunction, isCancelled, isLoss, isPending, isTerminal, isWin, normalCDF, normalPDF };
|
|
1127
|
+
export { type AgencyPairFilter, AgencyPairModule, type AgencyPairStats, type AgencyPairStatus, AuthModule, type BackendHealth, type Bid, BidModule, type BidStatus, type CancelBidResult, type Candle, type Constraints, type Currency, GameChannel, type GameConfig, type GridConfig, type LeaderboardEntry, LeaderboardModule, type LeaderboardPeriod, type LeaderboardSortBy, LocaleModule, type LocaleRefreshResult, type LocaleResponse, type LocaleTranslations, type LoginResult, type Me, type MqttAcceptedBid, type MqttAgencyPairStatsEvent, type MqttBalanceEvent, type MqttBidAcceptedEvent, type MqttBidLostEvent, type MqttBidWonEvent, type MqttCandleEvent, type MqttConfigEvent, type MqttIdealConfigEvent, type MqttWalletBalanceEvent, type MyRank, type NetworkLevel, type NetworkQuality, NetworkQualityMonitor, type Pair, type PairInfo, PairModule, type PlaceBidInput, type RankBoard, type RankEntry, type RankPeriod, type RankSort, RealtimeModule, type Sample, type SampleReason, type SignalSource, type SortDir, TaphubAuthError, TaphubClient, type TaphubClientConfig, TaphubError, TaphubEventBus, type TaphubEventMap, TaphubNetworkError, TaphubServerError, TaphubSlippageError, TaphubStorage, type TaphubStorageAdapter, TaphubValidationError, type User, UserModule, type UserPnL, type UserPnLPeriod, type Wallet as UserWallet, type Wallet$1 as Wallet, type WalletBalanceReason, WalletChannel, adaptiveSimpson, autoDetectStorage, calculateProbWin, calculateProbWin_v2, errorFunction, isCancelled, isLoss, isPending, isTerminal, isWin, normalCDF, normalPDF };
|
package/dist/index.js
CHANGED
|
@@ -543,6 +543,41 @@ function normaliseLeaderboard(rows) {
|
|
|
543
543
|
gain: row.gain
|
|
544
544
|
}));
|
|
545
545
|
}
|
|
546
|
+
function normaliseRankEntry(row) {
|
|
547
|
+
return {
|
|
548
|
+
userId: row.userId,
|
|
549
|
+
loginBy: row.loginBy,
|
|
550
|
+
username: row.username,
|
|
551
|
+
rank: row.rank,
|
|
552
|
+
pnl: row.pnl,
|
|
553
|
+
vol: row.vol,
|
|
554
|
+
payout: row.payout,
|
|
555
|
+
wins: row.wins,
|
|
556
|
+
bids: row.bids
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
function normaliseRankBoard(wire) {
|
|
560
|
+
if (wire == null || typeof wire !== "object") {
|
|
561
|
+
throw new TaphubServerError("Invalid response from server", {
|
|
562
|
+
code: "InvalidResponse"
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
return {
|
|
566
|
+
period: wire.period,
|
|
567
|
+
range: { from: wire.range?.from, to: wire.range?.to },
|
|
568
|
+
sort: wire.sort,
|
|
569
|
+
sortDir: wire.sortDir,
|
|
570
|
+
total: wire.total,
|
|
571
|
+
entries: Array.isArray(wire.entries) ? wire.entries.map(normaliseRankEntry) : []
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function normaliseRankMe(wire) {
|
|
575
|
+
return {
|
|
576
|
+
rank: wire.rank,
|
|
577
|
+
total: wire.total,
|
|
578
|
+
entry: wire.entry ? normaliseRankEntry(wire.entry) : null
|
|
579
|
+
};
|
|
580
|
+
}
|
|
546
581
|
|
|
547
582
|
// src/modules/leaderboard/queries.ts
|
|
548
583
|
var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!) {
|
|
@@ -550,6 +585,23 @@ var LEADERBOARD_QUERY = `query Leaderboard($period: String!, $sort_by: String!)
|
|
|
550
585
|
user_id username rank total_bids total_wins total_wagered total_payout gain
|
|
551
586
|
}
|
|
552
587
|
}`;
|
|
588
|
+
var RANK_LEADERBOARD_V2_QUERY = `query RankLeaderboardV2($input: RankBoardInput!) {
|
|
589
|
+
rank_leaderboardV2(input: $input) {
|
|
590
|
+
period
|
|
591
|
+
range { from to }
|
|
592
|
+
sort
|
|
593
|
+
sortDir
|
|
594
|
+
total
|
|
595
|
+
entries { userId loginBy username rank pnl vol payout wins bids }
|
|
596
|
+
}
|
|
597
|
+
}`;
|
|
598
|
+
var RANK_ME_QUERY = `query RankMe($input: RankMeInput!) {
|
|
599
|
+
rank_me(input: $input) {
|
|
600
|
+
rank
|
|
601
|
+
total
|
|
602
|
+
entry { userId loginBy username rank pnl vol payout wins bids }
|
|
603
|
+
}
|
|
604
|
+
}`;
|
|
553
605
|
|
|
554
606
|
// src/modules/leaderboard/index.ts
|
|
555
607
|
var LeaderboardModule = class {
|
|
@@ -557,6 +609,11 @@ var LeaderboardModule = class {
|
|
|
557
609
|
constructor(deps) {
|
|
558
610
|
this.#graphql = deps.graphql;
|
|
559
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* @deprecated Use {@link LeaderboardModule.rankBoard}. The backend
|
|
614
|
+
* `leaderboard` query is `@deprecated` in favour of `rank_leaderboardV2`
|
|
615
|
+
* (duration presets, pnl/vol sort, pagination, current-user `me`).
|
|
616
|
+
*/
|
|
560
617
|
async list(args) {
|
|
561
618
|
const body = await this.#graphql.publicRequest(
|
|
562
619
|
LEADERBOARD_QUERY,
|
|
@@ -565,6 +622,55 @@ var LeaderboardModule = class {
|
|
|
565
622
|
);
|
|
566
623
|
return normaliseLeaderboard(body.leaderboard);
|
|
567
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Fetch the public duration-scoped rank board (`rank_leaderboardV2`).
|
|
627
|
+
*
|
|
628
|
+
* Supports the fixed period presets plus `custom` (which requires an
|
|
629
|
+
* hour-aligned `range`), `pnl`/`vol` sort with an explicit direction, offset
|
|
630
|
+
* pagination, and a `total` count for "#X of N" UI. Optional args are omitted
|
|
631
|
+
* from the wire `input` when undefined so the server defaults apply
|
|
632
|
+
* (`sort = pnl`, `sortDir = desc`, `limit = 50`, `offset = 0`).
|
|
633
|
+
*
|
|
634
|
+
* bid-260606-leaderboard-split-my-rank: the board is **public and identical for
|
|
635
|
+
* every caller** — it carries no per-user data. For the signed-in caller's own
|
|
636
|
+
* row+rank, use {@link LeaderboardModule.myRank}.
|
|
637
|
+
*/
|
|
638
|
+
async rankBoard(args) {
|
|
639
|
+
const input = { period: args.period };
|
|
640
|
+
if (args.range) input.range = { from: args.range.from, to: args.range.to };
|
|
641
|
+
if (args.sort) input.sort = args.sort;
|
|
642
|
+
if (args.sortDir) input.sortDir = args.sortDir;
|
|
643
|
+
if (args.limit != null || args.offset != null) {
|
|
644
|
+
input.p = { limit: args.limit, offset: args.offset };
|
|
645
|
+
}
|
|
646
|
+
const body = await this.#graphql.publicRequest(
|
|
647
|
+
RANK_LEADERBOARD_V2_QUERY,
|
|
648
|
+
{ input },
|
|
649
|
+
args.signal ? { signal: args.signal } : void 0
|
|
650
|
+
);
|
|
651
|
+
return normaliseRankBoard(body.rank_leaderboardV2);
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Fetch the signed-in caller's own row + rank for the same window (`rank_me`) —
|
|
655
|
+
* the per-user companion to {@link LeaderboardModule.rankBoard}.
|
|
656
|
+
*
|
|
657
|
+
* Unlike the board, this attaches the user JWT (`request`, not `publicRequest`)
|
|
658
|
+
* so the backend resolves the caller. Returns `null` when no user is signed in
|
|
659
|
+
* (the backend returns `rank_me: null`). `MyRank.entry` is `null` when the
|
|
660
|
+
* caller has no activity in the window.
|
|
661
|
+
*/
|
|
662
|
+
async myRank(args) {
|
|
663
|
+
const input = { period: args.period };
|
|
664
|
+
if (args.range) input.range = { from: args.range.from, to: args.range.to };
|
|
665
|
+
if (args.sort) input.sort = args.sort;
|
|
666
|
+
if (args.sortDir) input.sortDir = args.sortDir;
|
|
667
|
+
const body = await this.#graphql.request(
|
|
668
|
+
RANK_ME_QUERY,
|
|
669
|
+
{ input },
|
|
670
|
+
args.signal ? { signal: args.signal } : void 0
|
|
671
|
+
);
|
|
672
|
+
return body.rank_me ? normaliseRankMe(body.rank_me) : null;
|
|
673
|
+
}
|
|
568
674
|
};
|
|
569
675
|
|
|
570
676
|
// src/modules/locale/normalise.ts
|