@hyve-sdk/js 2.3.0 → 2.4.1

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/README.md CHANGED
@@ -5,53 +5,27 @@ TypeScript SDK for integrating games with the Hyve platform. Provides authentica
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- pnpm add @hyve-sdk/js
8
+ bun add @hyve-sdk/js
9
9
  ```
10
10
 
11
11
  ## Quick Start
12
12
 
13
- ```ts
14
- import { HyveClient } from "@hyve-sdk/js";
15
-
16
- // Authentication is automatic — the SDK reads hyve-access and game-id from the URL
17
- const client = new HyveClient();
18
-
19
- console.log("User ID:", client.getUserId());
20
- console.log("Game ID:", client.getGameId());
21
- console.log("Authenticated:", client.isUserAuthenticated());
22
- ```
23
-
24
- The SDK reads authentication from URL parameters automatically during construction:
25
-
26
- ```
27
- https://your-game.com?hyve-access=eyJhbGci...&game-id=my-game
28
- ```
29
-
30
- **Environment detection** happens automatically from the parent page URL (games run in iframes):
31
- - Dev: `marvin.dev.hyve.gg` or `dev.hyve.gg`
32
- - Prod: `marvin.hyve.gg` or `hyve.gg`
33
- - Override with `isDev` in config for local testing only
34
-
35
- ## React Integration
36
-
37
- Import from `@hyve-sdk/js/react` for the React provider and hook:
38
-
39
13
  ```tsx
40
14
  import { HyveSdkProvider, useHyveSdk } from "@hyve-sdk/js/react";
41
15
 
42
16
  function App() {
43
17
  return (
44
- <HyveSdkProvider config={{ isDev: true }}>
18
+ <HyveSdkProvider>
45
19
  <Game />
46
20
  </HyveSdkProvider>
47
21
  );
48
22
  }
49
23
 
50
24
  function Game() {
51
- const sdk = useHyveSdk();
25
+ const hyve = useHyveSdk();
52
26
 
53
27
  const handleScore = () => {
54
- sdk.sendTelemetry("game", "player", "score_submitted", null, null, { score: 1000 });
28
+ hyve.sendTelemetry("game", "player", "score_submitted", null, null, { score: 1000 });
55
29
  };
56
30
 
57
31
  return <button onClick={handleScore}>Submit Score</button>;
@@ -61,17 +35,32 @@ function Game() {
61
35
  You can also pass a pre-created client:
62
36
 
63
37
  ```tsx
64
- const client = new HyveClient({ isDev: true });
38
+ import { HyveClient } from "@hyve-sdk/js";
39
+ import { HyveSdkProvider } from "@hyve-sdk/js/react";
40
+
41
+ const client = new HyveClient();
65
42
 
66
43
  <HyveSdkProvider client={client}>
67
44
  <App />
68
45
  </HyveSdkProvider>
69
46
  ```
70
47
 
48
+ The SDK reads authentication from URL parameters automatically during construction:
49
+
50
+ ```
51
+ https://your-game.com?hyve-access=eyJhbGci...&game-id=my-game
52
+ ```
53
+
54
+ **Environment detection** happens automatically from the parent page URL (games run in iframes):
55
+ - Dev: `marvin.dev.hyve.gg` or `dev.hyve.gg`
56
+ - Prod: `marvin.hyve.gg` or `hyve.gg`
57
+
71
58
  ## Telemetry
72
59
 
73
60
  ```ts
74
- await client.sendTelemetry(
61
+ const hyve = useHyveSdk();
62
+
63
+ await hyve.sendTelemetry(
75
64
  "game", // location
76
65
  "player", // category
77
66
  "action", // action
@@ -80,7 +69,8 @@ await client.sendTelemetry(
80
69
  { // event details (optional)
81
70
  damage: 100,
82
71
  targetId: "enemy-123",
83
- }
72
+ },
73
+ "playgama" // platform ID (optional)
84
74
  );
85
75
  ```
86
76
 
@@ -91,26 +81,34 @@ Requires a valid `hyve-access` JWT and `game-id` in the URL.
91
81
  Save and retrieve game data with either cloud (default) or local storage:
92
82
 
93
83
  ```ts
84
+ const hyve = useHyveSdk();
85
+
94
86
  // Save a value
95
- await client.saveGameData("player_level", 5);
96
- await client.saveGameData("settings", { volume: 0.8, fullscreen: true });
87
+ await hyve.saveGameData("player_level", 5);
88
+ await hyve.saveGameData("settings", { volume: 0.8, fullscreen: true });
89
+
90
+ // Atomic operations — read-modify-write server-side
91
+ await hyve.saveGameData("coins", 100, "add"); // increment
92
+ await hyve.saveGameData("high_score", 9999, "max"); // keep highest
93
+ await hyve.saveGameData("stats", 1, "add", "level"); // nested path
97
94
 
98
95
  // Get a value
99
- const item = await client.getGameData("player_level");
96
+ const item = await hyve.getGameData("player_level");
100
97
  console.log(item?.value); // 5
101
98
 
102
- // Batch save
103
- await client.batchSaveGameData([
99
+ // Batch save (per-item operations supported)
100
+ await hyve.batchSaveGameData([
104
101
  { key: "coins", value: 1200 },
105
102
  { key: "lives", value: 3 },
103
+ { key: "high_score", value: 5000, operation: "max" },
106
104
  ]);
107
105
 
108
106
  // Batch get
109
- const items = await client.getMultipleGameData(["coins", "lives"]);
107
+ const items = await hyve.getMultipleGameData(["coins", "lives"]);
110
108
 
111
109
  // Delete
112
- await client.deleteGameData("temp_key");
113
- await client.deleteMultipleGameData(["key1", "key2"]);
110
+ await hyve.deleteGameData("temp_key");
111
+ await hyve.deleteMultipleGameData(["key1", "key2"]);
114
112
  ```
115
113
 
116
114
  ### Storage Modes
@@ -119,13 +117,13 @@ await client.deleteMultipleGameData(["key1", "key2"]);
119
117
  // Set mode at construction
120
118
  const client = new HyveClient({ storageMode: "local" });
121
119
 
122
- // Or override per-call
123
- await client.saveGameData("key", "value", "local");
124
- await client.getGameData("key", "cloud");
120
+ // Or override per-call (storage is the last parameter)
121
+ await hyve.saveGameData("key", "value", undefined, undefined, "local");
122
+ await hyve.getGameData("key", "cloud");
125
123
 
126
124
  // Change mode at runtime
127
- client.configureStorage("cloud");
128
- console.log(client.getStorageMode()); // "cloud"
125
+ hyve.configureStorage("cloud");
126
+ console.log(hyve.getStorageMode()); // "cloud"
129
127
  ```
130
128
 
131
129
  | Mode | Description |
@@ -133,11 +131,52 @@ console.log(client.getStorageMode()); // "cloud"
133
131
  | `cloud` | Synced to backend API (default) |
134
132
  | `local` | Browser `localStorage`, device-only |
135
133
 
134
+ ## Leaderboards
135
+
136
+ Rank players by numeric values stored in persistent game data.
137
+
138
+ ```ts
139
+ const hyve = useHyveSdk();
140
+
141
+ // 1. Store the player's score
142
+ await hyve.saveGameData("high_score", 4200);
143
+
144
+ // 2. Fetch the leaderboard
145
+ const board = await hyve.getGameDataLeaderboard({ key: "high_score" });
146
+
147
+ for (const entry of board.entries) {
148
+ console.log(`#${entry.rank} ${entry.username}: ${entry.score}`);
149
+ }
150
+
151
+ // The caller's own rank is included automatically
152
+ if (board.user_position) {
153
+ console.log("Your rank:", board.user_position.rank);
154
+ }
155
+ ```
156
+
157
+ Use `score_path` to rank by a nested field, and `sort`/`limit`/`cursor` for pagination:
158
+
159
+ ```ts
160
+ const board = await hyve.getGameDataLeaderboard({
161
+ key: "tetris_progress",
162
+ score_path: "stats.score", // dot-notation path to numeric field
163
+ sort: "desc", // "asc" | "desc" (default: "desc")
164
+ limit: 20, // 1–100 (default: 10)
165
+ });
166
+
167
+ if (board.has_more && board.next_cursor) {
168
+ const next = await hyve.getGameDataLeaderboard({
169
+ key: "tetris_progress",
170
+ cursor: board.next_cursor,
171
+ });
172
+ }
173
+ ```
174
+
136
175
  ## Ads
137
176
 
138
177
  Ads are disabled by default and must be explicitly configured.
139
178
 
140
- ```ts
179
+ ```tsx
141
180
  const client = new HyveClient({
142
181
  ads: {
143
182
  enabled: true,
@@ -147,13 +186,21 @@ const client = new HyveClient({
147
186
  },
148
187
  });
149
188
 
150
- const result = await client.showAd("rewarded");
189
+ <HyveSdkProvider client={client}>
190
+ <App />
191
+ </HyveSdkProvider>
192
+ ```
193
+
194
+ ```ts
195
+ const hyve = useHyveSdk();
196
+
197
+ const result = await hyve.showAd("rewarded");
151
198
  if (result.success) {
152
199
  console.log("User watched the ad");
153
200
  }
154
201
 
155
- await client.showAd("interstitial"); // between levels
156
- await client.showAd("preroll"); // game start
202
+ await hyve.showAd("interstitial"); // between levels
203
+ await hyve.showAd("preroll"); // game start
157
204
  ```
158
205
 
159
206
  | Ad Type | Use Case |
@@ -171,14 +218,16 @@ The SDK automatically routes ad calls through the appropriate platform SDK (Craz
171
218
  When running on CrazyGames, the SDK auto-initializes the CrazyGames SDK and routes ads through it. Use these additional lifecycle methods:
172
219
 
173
220
  ```ts
221
+ const hyve = useHyveSdk();
222
+
174
223
  // Call when gameplay begins (required by CrazyGames policy)
175
- await client.gameplayStart();
224
+ await hyve.gameplayStart();
176
225
 
177
226
  // Call when gameplay stops (paused, died, menu, etc.)
178
- await client.gameplayStop();
227
+ await hyve.gameplayStop();
179
228
 
180
229
  // Trigger a celebration effect on the CrazyGames website
181
- await client.happytime();
230
+ await hyve.happytime();
182
231
  ```
183
232
 
184
233
  ### Playgama
@@ -189,24 +238,32 @@ When running on Playgama, the SDK auto-initializes the Playgama Bridge and route
189
238
 
190
239
  Billing supports web (Stripe) and native (In-App Purchases) — platform is detected automatically.
191
240
 
192
- ```ts
241
+ ```tsx
193
242
  const client = new HyveClient({
194
243
  billing: {
195
244
  stripePublishableKey: "pk_live_...",
196
245
  },
197
246
  });
198
247
 
199
- if (client.isBillingAvailable()) {
200
- client.onPurchaseComplete((result) => {
248
+ <HyveSdkProvider client={client}>
249
+ <App />
250
+ </HyveSdkProvider>
251
+ ```
252
+
253
+ ```ts
254
+ const hyve = useHyveSdk();
255
+
256
+ if (hyve.isBillingAvailable()) {
257
+ hyve.onPurchaseComplete((result) => {
201
258
  console.log("Purchase successful:", result.transactionId);
202
259
  });
203
260
 
204
- client.onPurchaseError((result) => {
261
+ hyve.onPurchaseError((result) => {
205
262
  console.error("Purchase failed:", result.error?.message);
206
263
  });
207
264
 
208
- const products = await client.getBillingProducts();
209
- await client.purchaseProduct("price_1234");
265
+ const products = await hyve.getBillingProducts();
266
+ await hyve.purchaseProduct("price_1234");
210
267
  }
211
268
  ```
212
269
 
@@ -294,7 +351,6 @@ localStorage.setItem("HYVE_SDK_LOG_LEVEL", "error,warn");
294
351
 
295
352
  ```ts
296
353
  new HyveClient(config?: {
297
- isDev?: boolean; // Override env detection (local testing only)
298
354
  apiBaseUrl?: string; // Override API base URL
299
355
  storageMode?: "cloud" | "local";
300
356
  ads?: AdConfig;
@@ -310,6 +366,7 @@ new HyveClient(config?: {
310
366
  | `getGameId()` | `string \| null` | Game ID from URL or JWT |
311
367
  | `getSessionId()` | `string` | Unique session ID |
312
368
  | `getJwtToken()` | `string \| null` | Raw JWT string |
369
+ | `getApiBaseUrl()` | `string` | Current API base URL |
313
370
  | `isUserAuthenticated()` | `boolean` | Whether a user ID was extracted |
314
371
  | `hasJwtToken()` | `boolean` | Whether a JWT is present |
315
372
  | `logout()` | `void` | Clear auth state |
@@ -322,24 +379,26 @@ new HyveClient(config?: {
322
379
  | `callApi<T>(endpoint, options?)` | `Promise<T>` | Authenticated fetch to the Hyve API |
323
380
  | `getInventory()` | `Promise<Inventory>` | Get user inventory |
324
381
  | `getInventoryItem(itemId)` | `Promise<InventoryItem>` | Get a specific inventory item |
382
+ | `getMachineRender(machineId)` | `Promise<string>` | Fetch rendered HTML for a project machine |
325
383
 
326
384
  ### Telemetry
327
385
 
328
386
  | Method | Returns | Description |
329
387
  |--------|---------|-------------|
330
- | `sendTelemetry(location, category, action, subCategory?, subAction?, details?)` | `Promise<boolean>` | Send an analytics event |
388
+ | `sendTelemetry(location, category, action, subCategory?, subAction?, details?, platformId?)` | `Promise<boolean>` | Send an analytics event |
331
389
  | `updateTelemetryConfig(config)` | `void` | Update telemetry settings at runtime |
332
390
 
333
391
  ### Storage
334
392
 
335
393
  | Method | Returns | Description |
336
394
  |--------|---------|-------------|
337
- | `saveGameData(key, value, storage?)` | `Promise<SaveGameDataResponse>` | Save a single value |
338
- | `batchSaveGameData(items, storage?)` | `Promise<SaveGameDataResponse>` | Save multiple values |
395
+ | `saveGameData(key, value, operation?, path?, storage?)` | `Promise<SaveGameDataResponse>` | Save a single value; optional atomic operation and nested path |
396
+ | `batchSaveGameData(items, storage?)` | `Promise<BatchSaveGameDataResponse>` | Save multiple values; each item may include an operation and path |
339
397
  | `getGameData(key, storage?)` | `Promise<GameDataItem \| null>` | Get a single value |
340
398
  | `getMultipleGameData(keys, storage?)` | `Promise<GameDataItem[]>` | Get multiple values |
341
399
  | `deleteGameData(key, storage?)` | `Promise<boolean>` | Delete a single value |
342
- | `deleteMultipleGameData(keys, storage?)` | `Promise<number>` | Delete multiple values |
400
+ | `deleteMultipleGameData(keys, storage?)` | `Promise<number>` | Delete multiple values; returns count |
401
+ | `getGameDataLeaderboard(params)` | `Promise<GameDataLeaderboardResponse>` | Fetch players ranked by a game data key |
343
402
  | `configureStorage(mode)` | `void` | Set default storage mode |
344
403
  | `getStorageMode()` | `"cloud" \| "local"` | Get current storage mode |
345
404
 
package/dist/index.d.mts CHANGED
@@ -125,6 +125,47 @@ interface GameDataBatchItem {
125
125
  /** Dot-notation path targeting a nested field (e.g. "stats.score") */
126
126
  path?: string;
127
127
  }
128
+ /**
129
+ * Persistent Game Data Leaderboard Types
130
+ */
131
+ /** A single entry in the game data leaderboard */
132
+ interface GameDataLeaderboardEntry {
133
+ rank: number;
134
+ username: string;
135
+ avatar_url?: string | null;
136
+ hyve_user_id: string;
137
+ score: number;
138
+ }
139
+ /** The requesting user's position within the leaderboard */
140
+ interface GameDataLeaderboardUserPosition {
141
+ rank: number;
142
+ score: number;
143
+ entry: GameDataLeaderboardEntry;
144
+ }
145
+ /** Response from the game data leaderboard endpoint */
146
+ interface GameDataLeaderboardResponse {
147
+ entries: GameDataLeaderboardEntry[];
148
+ next_cursor?: string | null;
149
+ has_more: boolean;
150
+ /** Present when the authenticated user has data for the queried key */
151
+ user_position?: GameDataLeaderboardUserPosition | null;
152
+ }
153
+ /** Parameters for fetching a game data leaderboard */
154
+ interface GetGameDataLeaderboardParams {
155
+ /** Data key to rank users by (e.g. "high_score", "lines_cleared") */
156
+ key: string;
157
+ /**
158
+ * Dot-notation path to extract a numeric score from a nested JSON value.
159
+ * Leave empty to use the top-level value (e.g. "stats.score").
160
+ */
161
+ score_path?: string;
162
+ /** Sort direction - "asc" or "desc" (default: "desc") */
163
+ sort?: 'asc' | 'desc';
164
+ /** Number of results per page, 1-100 (default: 10) */
165
+ limit?: number;
166
+ /** Pagination cursor from a previous response's next_cursor */
167
+ cursor?: string;
168
+ }
128
169
 
129
170
  /**
130
171
  * Ads Service for Hyve SDK
@@ -586,6 +627,13 @@ declare class HyveClient {
586
627
  * @returns Promise resolving to number of entries deleted
587
628
  */
588
629
  deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
630
+ /**
631
+ * Fetch the persistent game data leaderboard for a given key.
632
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
633
+ * @param params Leaderboard query parameters (key is required)
634
+ * @returns Promise resolving to the leaderboard response including the caller's position
635
+ */
636
+ getGameDataLeaderboard(params: GetGameDataLeaderboardParams): Promise<GameDataLeaderboardResponse>;
589
637
  /**
590
638
  * Configure storage mode
591
639
  * @param mode Storage mode ('cloud' or 'local')
@@ -1095,4 +1143,4 @@ declare class NativeBridge {
1095
1143
  */
1096
1144
  declare function generateUUID(): string;
1097
1145
 
1098
- export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
1146
+ export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataLeaderboardEntry, type GameDataLeaderboardResponse, type GameDataLeaderboardUserPosition, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataLeaderboardParams, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
package/dist/index.d.ts CHANGED
@@ -125,6 +125,47 @@ interface GameDataBatchItem {
125
125
  /** Dot-notation path targeting a nested field (e.g. "stats.score") */
126
126
  path?: string;
127
127
  }
128
+ /**
129
+ * Persistent Game Data Leaderboard Types
130
+ */
131
+ /** A single entry in the game data leaderboard */
132
+ interface GameDataLeaderboardEntry {
133
+ rank: number;
134
+ username: string;
135
+ avatar_url?: string | null;
136
+ hyve_user_id: string;
137
+ score: number;
138
+ }
139
+ /** The requesting user's position within the leaderboard */
140
+ interface GameDataLeaderboardUserPosition {
141
+ rank: number;
142
+ score: number;
143
+ entry: GameDataLeaderboardEntry;
144
+ }
145
+ /** Response from the game data leaderboard endpoint */
146
+ interface GameDataLeaderboardResponse {
147
+ entries: GameDataLeaderboardEntry[];
148
+ next_cursor?: string | null;
149
+ has_more: boolean;
150
+ /** Present when the authenticated user has data for the queried key */
151
+ user_position?: GameDataLeaderboardUserPosition | null;
152
+ }
153
+ /** Parameters for fetching a game data leaderboard */
154
+ interface GetGameDataLeaderboardParams {
155
+ /** Data key to rank users by (e.g. "high_score", "lines_cleared") */
156
+ key: string;
157
+ /**
158
+ * Dot-notation path to extract a numeric score from a nested JSON value.
159
+ * Leave empty to use the top-level value (e.g. "stats.score").
160
+ */
161
+ score_path?: string;
162
+ /** Sort direction - "asc" or "desc" (default: "desc") */
163
+ sort?: 'asc' | 'desc';
164
+ /** Number of results per page, 1-100 (default: 10) */
165
+ limit?: number;
166
+ /** Pagination cursor from a previous response's next_cursor */
167
+ cursor?: string;
168
+ }
128
169
 
129
170
  /**
130
171
  * Ads Service for Hyve SDK
@@ -586,6 +627,13 @@ declare class HyveClient {
586
627
  * @returns Promise resolving to number of entries deleted
587
628
  */
588
629
  deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
630
+ /**
631
+ * Fetch the persistent game data leaderboard for a given key.
632
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
633
+ * @param params Leaderboard query parameters (key is required)
634
+ * @returns Promise resolving to the leaderboard response including the caller's position
635
+ */
636
+ getGameDataLeaderboard(params: GetGameDataLeaderboardParams): Promise<GameDataLeaderboardResponse>;
589
637
  /**
590
638
  * Configure storage mode
591
639
  * @param mode Storage mode ('cloud' or 'local')
@@ -1095,4 +1143,4 @@ declare class NativeBridge {
1095
1143
  */
1096
1144
  declare function generateUUID(): string;
1097
1145
 
1098
- export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
1146
+ export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataLeaderboardEntry, type GameDataLeaderboardResponse, type GameDataLeaderboardUserPosition, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataLeaderboardParams, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
package/dist/index.js CHANGED
@@ -2044,6 +2044,26 @@ var HyveClient = class {
2044
2044
  logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
2045
2045
  return deletedCount;
2046
2046
  }
2047
+ /**
2048
+ * Fetch the persistent game data leaderboard for a given key.
2049
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
2050
+ * @param params Leaderboard query parameters (key is required)
2051
+ * @returns Promise resolving to the leaderboard response including the caller's position
2052
+ */
2053
+ async getGameDataLeaderboard(params) {
2054
+ const gameId = this.requireGameId();
2055
+ logger.debug(`Fetching game data leaderboard: ${gameId}/${params.key}`);
2056
+ const query = new URLSearchParams({ game_id: gameId, key: params.key });
2057
+ if (params.score_path) query.set("score_path", params.score_path);
2058
+ if (params.sort) query.set("sort", params.sort);
2059
+ if (params.limit !== void 0) query.set("limit", params.limit.toString());
2060
+ if (params.cursor) query.set("cursor", params.cursor);
2061
+ const response = await this.callApi(
2062
+ `/api/v1/leaderboards/game-data?${query}`
2063
+ );
2064
+ logger.info(`Game data leaderboard fetched: ${response.entries.length} entries`);
2065
+ return response;
2066
+ }
2047
2067
  /**
2048
2068
  * Configure storage mode
2049
2069
  * @param mode Storage mode ('cloud' or 'local')
package/dist/index.mjs CHANGED
@@ -2004,6 +2004,26 @@ var HyveClient = class {
2004
2004
  logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
2005
2005
  return deletedCount;
2006
2006
  }
2007
+ /**
2008
+ * Fetch the persistent game data leaderboard for a given key.
2009
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
2010
+ * @param params Leaderboard query parameters (key is required)
2011
+ * @returns Promise resolving to the leaderboard response including the caller's position
2012
+ */
2013
+ async getGameDataLeaderboard(params) {
2014
+ const gameId = this.requireGameId();
2015
+ logger.debug(`Fetching game data leaderboard: ${gameId}/${params.key}`);
2016
+ const query = new URLSearchParams({ game_id: gameId, key: params.key });
2017
+ if (params.score_path) query.set("score_path", params.score_path);
2018
+ if (params.sort) query.set("sort", params.sort);
2019
+ if (params.limit !== void 0) query.set("limit", params.limit.toString());
2020
+ if (params.cursor) query.set("cursor", params.cursor);
2021
+ const response = await this.callApi(
2022
+ `/api/v1/leaderboards/game-data?${query}`
2023
+ );
2024
+ logger.info(`Game data leaderboard fetched: ${response.entries.length} entries`);
2025
+ return response;
2026
+ }
2007
2027
  /**
2008
2028
  * Configure storage mode
2009
2029
  * @param mode Storage mode ('cloud' or 'local')
package/dist/react.d.mts CHANGED
@@ -81,6 +81,47 @@ interface GameDataBatchItem {
81
81
  /** Dot-notation path targeting a nested field (e.g. "stats.score") */
82
82
  path?: string;
83
83
  }
84
+ /**
85
+ * Persistent Game Data Leaderboard Types
86
+ */
87
+ /** A single entry in the game data leaderboard */
88
+ interface GameDataLeaderboardEntry {
89
+ rank: number;
90
+ username: string;
91
+ avatar_url?: string | null;
92
+ hyve_user_id: string;
93
+ score: number;
94
+ }
95
+ /** The requesting user's position within the leaderboard */
96
+ interface GameDataLeaderboardUserPosition {
97
+ rank: number;
98
+ score: number;
99
+ entry: GameDataLeaderboardEntry;
100
+ }
101
+ /** Response from the game data leaderboard endpoint */
102
+ interface GameDataLeaderboardResponse {
103
+ entries: GameDataLeaderboardEntry[];
104
+ next_cursor?: string | null;
105
+ has_more: boolean;
106
+ /** Present when the authenticated user has data for the queried key */
107
+ user_position?: GameDataLeaderboardUserPosition | null;
108
+ }
109
+ /** Parameters for fetching a game data leaderboard */
110
+ interface GetGameDataLeaderboardParams {
111
+ /** Data key to rank users by (e.g. "high_score", "lines_cleared") */
112
+ key: string;
113
+ /**
114
+ * Dot-notation path to extract a numeric score from a nested JSON value.
115
+ * Leave empty to use the top-level value (e.g. "stats.score").
116
+ */
117
+ score_path?: string;
118
+ /** Sort direction - "asc" or "desc" (default: "desc") */
119
+ sort?: 'asc' | 'desc';
120
+ /** Number of results per page, 1-100 (default: 10) */
121
+ limit?: number;
122
+ /** Pagination cursor from a previous response's next_cursor */
123
+ cursor?: string;
124
+ }
84
125
 
85
126
  /**
86
127
  * Ads Service for Hyve SDK
@@ -361,6 +402,13 @@ declare class HyveClient {
361
402
  * @returns Promise resolving to number of entries deleted
362
403
  */
363
404
  deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
405
+ /**
406
+ * Fetch the persistent game data leaderboard for a given key.
407
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
408
+ * @param params Leaderboard query parameters (key is required)
409
+ * @returns Promise resolving to the leaderboard response including the caller's position
410
+ */
411
+ getGameDataLeaderboard(params: GetGameDataLeaderboardParams): Promise<GameDataLeaderboardResponse>;
364
412
  /**
365
413
  * Configure storage mode
366
414
  * @param mode Storage mode ('cloud' or 'local')
package/dist/react.d.ts CHANGED
@@ -81,6 +81,47 @@ interface GameDataBatchItem {
81
81
  /** Dot-notation path targeting a nested field (e.g. "stats.score") */
82
82
  path?: string;
83
83
  }
84
+ /**
85
+ * Persistent Game Data Leaderboard Types
86
+ */
87
+ /** A single entry in the game data leaderboard */
88
+ interface GameDataLeaderboardEntry {
89
+ rank: number;
90
+ username: string;
91
+ avatar_url?: string | null;
92
+ hyve_user_id: string;
93
+ score: number;
94
+ }
95
+ /** The requesting user's position within the leaderboard */
96
+ interface GameDataLeaderboardUserPosition {
97
+ rank: number;
98
+ score: number;
99
+ entry: GameDataLeaderboardEntry;
100
+ }
101
+ /** Response from the game data leaderboard endpoint */
102
+ interface GameDataLeaderboardResponse {
103
+ entries: GameDataLeaderboardEntry[];
104
+ next_cursor?: string | null;
105
+ has_more: boolean;
106
+ /** Present when the authenticated user has data for the queried key */
107
+ user_position?: GameDataLeaderboardUserPosition | null;
108
+ }
109
+ /** Parameters for fetching a game data leaderboard */
110
+ interface GetGameDataLeaderboardParams {
111
+ /** Data key to rank users by (e.g. "high_score", "lines_cleared") */
112
+ key: string;
113
+ /**
114
+ * Dot-notation path to extract a numeric score from a nested JSON value.
115
+ * Leave empty to use the top-level value (e.g. "stats.score").
116
+ */
117
+ score_path?: string;
118
+ /** Sort direction - "asc" or "desc" (default: "desc") */
119
+ sort?: 'asc' | 'desc';
120
+ /** Number of results per page, 1-100 (default: 10) */
121
+ limit?: number;
122
+ /** Pagination cursor from a previous response's next_cursor */
123
+ cursor?: string;
124
+ }
84
125
 
85
126
  /**
86
127
  * Ads Service for Hyve SDK
@@ -361,6 +402,13 @@ declare class HyveClient {
361
402
  * @returns Promise resolving to number of entries deleted
362
403
  */
363
404
  deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
405
+ /**
406
+ * Fetch the persistent game data leaderboard for a given key.
407
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
408
+ * @param params Leaderboard query parameters (key is required)
409
+ * @returns Promise resolving to the leaderboard response including the caller's position
410
+ */
411
+ getGameDataLeaderboard(params: GetGameDataLeaderboardParams): Promise<GameDataLeaderboardResponse>;
364
412
  /**
365
413
  * Configure storage mode
366
414
  * @param mode Storage mode ('cloud' or 'local')
package/dist/react.js CHANGED
@@ -1995,6 +1995,26 @@ var HyveClient = class {
1995
1995
  logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
1996
1996
  return deletedCount;
1997
1997
  }
1998
+ /**
1999
+ * Fetch the persistent game data leaderboard for a given key.
2000
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
2001
+ * @param params Leaderboard query parameters (key is required)
2002
+ * @returns Promise resolving to the leaderboard response including the caller's position
2003
+ */
2004
+ async getGameDataLeaderboard(params) {
2005
+ const gameId = this.requireGameId();
2006
+ logger.debug(`Fetching game data leaderboard: ${gameId}/${params.key}`);
2007
+ const query = new URLSearchParams({ game_id: gameId, key: params.key });
2008
+ if (params.score_path) query.set("score_path", params.score_path);
2009
+ if (params.sort) query.set("sort", params.sort);
2010
+ if (params.limit !== void 0) query.set("limit", params.limit.toString());
2011
+ if (params.cursor) query.set("cursor", params.cursor);
2012
+ const response = await this.callApi(
2013
+ `/api/v1/leaderboards/game-data?${query}`
2014
+ );
2015
+ logger.info(`Game data leaderboard fetched: ${response.entries.length} entries`);
2016
+ return response;
2017
+ }
1998
2018
  /**
1999
2019
  * Configure storage mode
2000
2020
  * @param mode Storage mode ('cloud' or 'local')
package/dist/react.mjs CHANGED
@@ -1974,6 +1974,26 @@ var HyveClient = class {
1974
1974
  logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
1975
1975
  return deletedCount;
1976
1976
  }
1977
+ /**
1978
+ * Fetch the persistent game data leaderboard for a given key.
1979
+ * Rankings are derived from numeric values stored via saveGameData / batchSaveGameData.
1980
+ * @param params Leaderboard query parameters (key is required)
1981
+ * @returns Promise resolving to the leaderboard response including the caller's position
1982
+ */
1983
+ async getGameDataLeaderboard(params) {
1984
+ const gameId = this.requireGameId();
1985
+ logger.debug(`Fetching game data leaderboard: ${gameId}/${params.key}`);
1986
+ const query = new URLSearchParams({ game_id: gameId, key: params.key });
1987
+ if (params.score_path) query.set("score_path", params.score_path);
1988
+ if (params.sort) query.set("sort", params.sort);
1989
+ if (params.limit !== void 0) query.set("limit", params.limit.toString());
1990
+ if (params.cursor) query.set("cursor", params.cursor);
1991
+ const response = await this.callApi(
1992
+ `/api/v1/leaderboards/game-data?${query}`
1993
+ );
1994
+ logger.info(`Game data leaderboard fetched: ${response.entries.length} entries`);
1995
+ return response;
1996
+ }
1977
1997
  /**
1978
1998
  * Configure storage mode
1979
1999
  * @param mode Storage mode ('cloud' or 'local')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyve-sdk/js",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "Hyve SDK - TypeScript wrapper for Hyve game server integration",
5
5
  "private": false,
6
6
  "publishConfig": {