@hyve-sdk/js 2.13.0 → 2.14.0-canary.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/react.mjs CHANGED
@@ -1177,6 +1177,7 @@ var PlaygamaService = class {
1177
1177
  var CRAZYGAMES_SDK_CDN = "https://sdk.crazygames.com/crazygames-sdk-v2.js";
1178
1178
  var CrazyGamesService = class {
1179
1179
  initialized = false;
1180
+ environment = null;
1180
1181
  /**
1181
1182
  * Detects if the game is running on the CrazyGames platform.
1182
1183
  * Games on CrazyGames run inside an iframe, so we check document.referrer
@@ -1218,6 +1219,7 @@ var CrazyGamesService = class {
1218
1219
  logger.warn("[CrazyGamesService] Unexpected environment:", env);
1219
1220
  return false;
1220
1221
  }
1222
+ this.environment = env;
1221
1223
  this.initialized = true;
1222
1224
  return true;
1223
1225
  } catch (error) {
@@ -1328,6 +1330,88 @@ var CrazyGamesService = class {
1328
1330
  if (!this.initialized) return;
1329
1331
  window.CrazyGames?.SDK.game.happytime();
1330
1332
  }
1333
+ /**
1334
+ * Returns the resolved CrazyGames environment ('crazygames' | 'local' |
1335
+ * 'disabled'), or null if the SDK has not initialized yet. Used to
1336
+ * auto-select the CrazyGames storage adapter.
1337
+ */
1338
+ getEnvironment() {
1339
+ return this.environment;
1340
+ }
1341
+ /**
1342
+ * Whether the CrazyGames account system is present (sync). When false,
1343
+ * there is no logged-in user concept and telemetry falls back to guests.
1344
+ */
1345
+ isUserAccountAvailable() {
1346
+ if (!this.initialized) return false;
1347
+ return window.CrazyGames?.SDK.user.isUserAccountAvailable ?? false;
1348
+ }
1349
+ /**
1350
+ * Fetches the current CrazyGames user, or null if the player is not logged
1351
+ * in (guest). The returned `__dangerousUserId` is client-asserted and used
1352
+ * only as a telemetry attribution label.
1353
+ */
1354
+ async getUser() {
1355
+ const sdk = window.CrazyGames?.SDK;
1356
+ if (!this.initialized || !sdk || !this.isUserAccountAvailable()) {
1357
+ return null;
1358
+ }
1359
+ try {
1360
+ return await sdk.user.getUser() ?? null;
1361
+ } catch (error) {
1362
+ logger.warn("[CrazyGamesService] getUser failed:", error);
1363
+ return null;
1364
+ }
1365
+ }
1366
+ /**
1367
+ * Registers a listener that fires when a guest logs in mid-session.
1368
+ * No-op if the SDK or account system is unavailable.
1369
+ */
1370
+ addAuthListener(callback) {
1371
+ const sdk = window.CrazyGames?.SDK;
1372
+ if (!this.initialized || !sdk || !this.isUserAccountAvailable()) return;
1373
+ try {
1374
+ sdk.user.addAuthListener(callback);
1375
+ } catch (error) {
1376
+ logger.warn("[CrazyGamesService] addAuthListener failed:", error);
1377
+ }
1378
+ }
1379
+ /** Removes a previously registered auth listener. */
1380
+ removeAuthListener(callback) {
1381
+ const sdk = window.CrazyGames?.SDK;
1382
+ if (!this.initialized || !sdk) return;
1383
+ try {
1384
+ sdk.user.removeAuthListener(callback);
1385
+ } catch (error) {
1386
+ logger.warn("[CrazyGamesService] removeAuthListener failed:", error);
1387
+ }
1388
+ }
1389
+ /**
1390
+ * Reads a value from the CrazyGames data store. Returns null when the SDK
1391
+ * is unavailable or the key is absent.
1392
+ */
1393
+ async dataGetItem(key) {
1394
+ const sdk = window.CrazyGames?.SDK;
1395
+ if (!this.initialized || !sdk) return null;
1396
+ const value = await sdk.data.getItem(key);
1397
+ return value ?? null;
1398
+ }
1399
+ /** Writes a value to the CrazyGames data store. */
1400
+ async dataSetItem(key, value) {
1401
+ const sdk = window.CrazyGames?.SDK;
1402
+ if (!this.initialized || !sdk) {
1403
+ throw new Error("CrazyGames SDK not initialized");
1404
+ }
1405
+ await sdk.data.setItem(key, value);
1406
+ }
1407
+ /** Removes a value from the CrazyGames data store. */
1408
+ async dataRemoveItem(key) {
1409
+ const sdk = window.CrazyGames?.SDK;
1410
+ if (!this.initialized || !sdk) {
1411
+ throw new Error("CrazyGames SDK not initialized");
1412
+ }
1413
+ await sdk.data.removeItem(key);
1414
+ }
1331
1415
  loadScript() {
1332
1416
  return new Promise((resolve, reject) => {
1333
1417
  if (window.CrazyGames?.SDK) {
@@ -1989,6 +2073,162 @@ var LocalStorageAdapter = class {
1989
2073
  return count;
1990
2074
  }
1991
2075
  };
2076
+ function isGameDataObject(value) {
2077
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2078
+ }
2079
+ function toNumber(value) {
2080
+ return typeof value === "number" ? value : 0;
2081
+ }
2082
+ function applyOperation(operation, current, operand) {
2083
+ switch (operation) {
2084
+ case "set":
2085
+ return operand;
2086
+ case "add":
2087
+ return toNumber(current) + toNumber(operand);
2088
+ case "subtract":
2089
+ return toNumber(current) - toNumber(operand);
2090
+ case "multiply":
2091
+ return toNumber(current) * toNumber(operand);
2092
+ case "divide": {
2093
+ const divisor = toNumber(operand);
2094
+ if (divisor === 0) throw new Error("Cannot divide by zero");
2095
+ return toNumber(current) / divisor;
2096
+ }
2097
+ case "modulo": {
2098
+ const divisor = toNumber(operand);
2099
+ if (divisor === 0) throw new Error("Cannot modulo by zero");
2100
+ return toNumber(current) % divisor;
2101
+ }
2102
+ // For min/max, a missing current has nothing to compare against — adopt the operand.
2103
+ case "min":
2104
+ return typeof current === "number" ? Math.min(current, toNumber(operand)) : operand;
2105
+ case "max":
2106
+ return typeof current === "number" ? Math.max(current, toNumber(operand)) : operand;
2107
+ case "append": {
2108
+ const base = Array.isArray(current) ? [...current] : current === void 0 || current === null ? [] : [current];
2109
+ if (Array.isArray(operand)) {
2110
+ base.push(...operand);
2111
+ } else {
2112
+ base.push(operand);
2113
+ }
2114
+ return base;
2115
+ }
2116
+ default:
2117
+ return operand;
2118
+ }
2119
+ }
2120
+ function getAtPath(value, path) {
2121
+ let current = value;
2122
+ for (const segment of path.split(".")) {
2123
+ if (!isGameDataObject(current)) return void 0;
2124
+ current = current[segment];
2125
+ }
2126
+ return current;
2127
+ }
2128
+ function setAtPath(value, path, newValue) {
2129
+ const segments = path.split(".");
2130
+ const root = isGameDataObject(value) ? { ...value } : {};
2131
+ let cursor = root;
2132
+ for (let i = 0; i < segments.length - 1; i++) {
2133
+ const segment = segments[i];
2134
+ const existing = cursor[segment];
2135
+ const next = isGameDataObject(existing) ? { ...existing } : {};
2136
+ cursor[segment] = next;
2137
+ cursor = next;
2138
+ }
2139
+ cursor[segments[segments.length - 1]] = newValue;
2140
+ return root;
2141
+ }
2142
+ var CrazyGamesStorageAdapter = class {
2143
+ constructor(service) {
2144
+ this.service = service;
2145
+ }
2146
+ getStorageKey(gameId, key) {
2147
+ return `${gameId}:${key}`;
2148
+ }
2149
+ async saveGameData(gameId, key, value, operation, path) {
2150
+ const storageKey = this.getStorageKey(gameId, key);
2151
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2152
+ const existingRaw = await this.service.dataGetItem(storageKey);
2153
+ const existing = existingRaw ? JSON.parse(existingRaw) : null;
2154
+ const createdAt = existing?.created_at ?? now;
2155
+ const useOperation = operation !== void 0;
2156
+ let storedValue;
2157
+ let opResult;
2158
+ if (path) {
2159
+ const current = getAtPath(existing?.value, path);
2160
+ const next = useOperation ? applyOperation(operation, current, value) : value;
2161
+ storedValue = setAtPath(existing?.value, path, next);
2162
+ opResult = next;
2163
+ } else {
2164
+ const current = existing?.value;
2165
+ const next = useOperation ? applyOperation(operation, current, value) : value;
2166
+ storedValue = next;
2167
+ opResult = next;
2168
+ }
2169
+ const item = {
2170
+ key,
2171
+ value: storedValue,
2172
+ created_at: createdAt,
2173
+ updated_at: now
2174
+ };
2175
+ await this.service.dataSetItem(storageKey, JSON.stringify(item));
2176
+ const response = { success: true, message: "Data saved successfully" };
2177
+ if (useOperation && operation !== "set") {
2178
+ response.result = opResult;
2179
+ }
2180
+ return response;
2181
+ }
2182
+ async batchSaveGameData(gameId, items) {
2183
+ const results = [];
2184
+ let usedOperation = false;
2185
+ for (const item of items) {
2186
+ if (item.operation !== void 0) usedOperation = true;
2187
+ try {
2188
+ const saved = await this.saveGameData(gameId, item.key, item.value, item.operation, item.path);
2189
+ results.push({ key: item.key, success: true, ...saved.result !== void 0 && { result: saved.result } });
2190
+ } catch (error) {
2191
+ results.push({
2192
+ key: item.key,
2193
+ success: false,
2194
+ error: error instanceof Error ? error.message : "Unknown error"
2195
+ });
2196
+ }
2197
+ }
2198
+ const allSucceeded = results.every((r) => r.success);
2199
+ return {
2200
+ success: allSucceeded,
2201
+ message: `${results.filter((r) => r.success).length}/${items.length} items saved`,
2202
+ ...usedOperation && { results }
2203
+ };
2204
+ }
2205
+ async getGameData(gameId, key) {
2206
+ const raw = await this.service.dataGetItem(this.getStorageKey(gameId, key));
2207
+ return raw ? JSON.parse(raw) : null;
2208
+ }
2209
+ async getMultipleGameData(gameId, keys) {
2210
+ const items = [];
2211
+ for (const key of keys) {
2212
+ const item = await this.getGameData(gameId, key);
2213
+ if (item) items.push(item);
2214
+ }
2215
+ return items;
2216
+ }
2217
+ async deleteGameData(gameId, key) {
2218
+ const storageKey = this.getStorageKey(gameId, key);
2219
+ const existing = await this.service.dataGetItem(storageKey);
2220
+ if (existing === null) return false;
2221
+ await this.service.dataRemoveItem(storageKey);
2222
+ return true;
2223
+ }
2224
+ async deleteMultipleGameData(gameId, keys) {
2225
+ let count = 0;
2226
+ for (const key of keys) {
2227
+ if (await this.deleteGameData(gameId, key)) count++;
2228
+ }
2229
+ return count;
2230
+ }
2231
+ };
1992
2232
 
1993
2233
  // src/core/client.ts
1994
2234
  function determineEnvironmentFromParentUrl() {
@@ -2035,6 +2275,11 @@ var HyveClient = class {
2035
2275
  storageMode;
2036
2276
  cloudStorageAdapter;
2037
2277
  localStorageAdapter;
2278
+ crazyGamesStorageAdapter = null;
2279
+ partnerApiKey = null;
2280
+ partnerApiBaseUrl = null;
2281
+ /** Raw (unprefixed) CrazyGames __dangerousUserId, seeded at init and on login. */
2282
+ crazyGamesUserId = null;
2038
2283
  /**
2039
2284
  * Creates a new HyveClient instance
2040
2285
  * @param config Optional configuration including telemetry and ads
@@ -2062,10 +2307,16 @@ var HyveClient = class {
2062
2307
  return success;
2063
2308
  });
2064
2309
  }
2310
+ this.partnerApiKey = config?.partnerApiKey ?? null;
2311
+ this.partnerApiBaseUrl = config?.partnerApiBaseUrl ?? null;
2065
2312
  if (typeof window !== "undefined" && CrazyGamesService.isCrazyGamesDomain()) {
2066
2313
  this.crazyGamesService = new CrazyGamesService();
2067
- this.crazyGamesInitPromise = this.crazyGamesService.initialize().then((success) => {
2314
+ this.crazyGamesStorageAdapter = new CrazyGamesStorageAdapter(this.crazyGamesService);
2315
+ this.crazyGamesInitPromise = this.crazyGamesService.initialize().then(async (success) => {
2068
2316
  logger.info("CrazyGames SDK initialized:", success);
2317
+ if (success) {
2318
+ await this.seedCrazyGamesUser();
2319
+ }
2069
2320
  return success;
2070
2321
  });
2071
2322
  }
@@ -2161,6 +2412,16 @@ var HyveClient = class {
2161
2412
  * @returns Promise resolving to boolean indicating success
2162
2413
  */
2163
2414
  async sendTelemetry(eventLocation, eventCategory, eventAction, eventSubCategory, eventSubAction, eventDetails, platformId) {
2415
+ if (this.partnerApiKey) {
2416
+ return this.sendPartnerTelemetry(
2417
+ eventLocation,
2418
+ eventCategory,
2419
+ eventAction,
2420
+ eventSubCategory,
2421
+ eventSubAction,
2422
+ eventDetails
2423
+ );
2424
+ }
2164
2425
  if (!this.jwtToken) {
2165
2426
  logger.error("JWT token required. Ensure hyve-access and game-id are present in the URL.");
2166
2427
  return false;
@@ -2170,42 +2431,11 @@ var HyveClient = class {
2170
2431
  return false;
2171
2432
  }
2172
2433
  try {
2173
- if (eventDetails) {
2174
- try {
2175
- if (typeof eventDetails === "string") {
2176
- JSON.parse(eventDetails);
2177
- } else if (typeof eventDetails === "object") {
2178
- JSON.stringify(eventDetails);
2179
- }
2180
- } catch (validationError) {
2181
- logger.error("Invalid JSON in eventDetails:", validationError);
2182
- logger.error("eventDetails value:", eventDetails);
2183
- return false;
2184
- }
2185
- }
2186
- let parsedEventDetails = {};
2187
- if (eventDetails) {
2188
- if (typeof eventDetails === "string") {
2189
- try {
2190
- parsedEventDetails = JSON.parse(eventDetails);
2191
- } catch {
2192
- }
2193
- } else {
2194
- parsedEventDetails = eventDetails;
2195
- }
2434
+ const enrichedEventDetails = this.enrichEventDetails(eventDetails);
2435
+ if (enrichedEventDetails === null) {
2436
+ return false;
2196
2437
  }
2197
2438
  const attribution = getAttributionData();
2198
- const enrichedEventDetails = {
2199
- // Device info
2200
- ...getEssentialDeviceInfo(),
2201
- // Attribution data
2202
- ...attribution,
2203
- // Timestamp and session context
2204
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2205
- session_id: this.sessionId,
2206
- // Event-specific details can override any of the above
2207
- ...parsedEventDetails
2208
- };
2209
2439
  const telemetryEvent = {
2210
2440
  game_id: this.gameId,
2211
2441
  session_id: this.sessionId,
@@ -2244,6 +2474,122 @@ var HyveClient = class {
2244
2474
  return false;
2245
2475
  }
2246
2476
  }
2477
+ /**
2478
+ * Validates and enriches user-provided event details with device info,
2479
+ * attribution data, and session context — matching the enrichment
2480
+ * platform-v2 applies in sendAnalyticsEvent. Shared by the JWT and partner
2481
+ * telemetry paths.
2482
+ * @returns Enriched details object, or null if eventDetails is not valid JSON.
2483
+ */
2484
+ enrichEventDetails(eventDetails) {
2485
+ let parsedEventDetails = {};
2486
+ if (eventDetails) {
2487
+ try {
2488
+ if (typeof eventDetails === "string") {
2489
+ parsedEventDetails = JSON.parse(eventDetails);
2490
+ } else if (typeof eventDetails === "object") {
2491
+ JSON.stringify(eventDetails);
2492
+ parsedEventDetails = eventDetails;
2493
+ }
2494
+ } catch (validationError) {
2495
+ logger.error("Invalid JSON in eventDetails:", validationError);
2496
+ logger.error("eventDetails value:", eventDetails);
2497
+ return null;
2498
+ }
2499
+ }
2500
+ const attribution = getAttributionData();
2501
+ return {
2502
+ // Device info
2503
+ ...getEssentialDeviceInfo(),
2504
+ // Attribution data
2505
+ ...attribution,
2506
+ // Timestamp and session context
2507
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2508
+ session_id: this.sessionId,
2509
+ // Event-specific details can override any of the above
2510
+ ...parsedEventDetails
2511
+ };
2512
+ }
2513
+ /**
2514
+ * Sends a telemetry event via the partner analytics endpoint using a partner
2515
+ * API key (x-api-key) instead of a hyve JWT. Used by externally-hosted games
2516
+ * such as CrazyGames. game_id is derived from the API key server-side and is
2517
+ * therefore not sent. hyve_user_id carries the `cg:`-prefixed CrazyGames id,
2518
+ * or a guest sentinel when the player is not logged in.
2519
+ */
2520
+ async sendPartnerTelemetry(eventLocation, eventCategory, eventAction, eventSubCategory, eventSubAction, eventDetails) {
2521
+ if (!this.partnerApiKey) {
2522
+ logger.error("Partner API key required for partner telemetry path.");
2523
+ return false;
2524
+ }
2525
+ if (this.crazyGamesService && this.crazyGamesInitPromise) {
2526
+ await this.crazyGamesInitPromise;
2527
+ }
2528
+ try {
2529
+ const enrichedEventDetails = this.enrichEventDetails(eventDetails);
2530
+ if (enrichedEventDetails === null) {
2531
+ return false;
2532
+ }
2533
+ const hyveUserId = this.crazyGamesUserId ? `cg:${this.crazyGamesUserId}` : "cg:guest";
2534
+ const partnerEvent = {
2535
+ session_id: this.sessionId,
2536
+ hyve_user_id: hyveUserId,
2537
+ event_location: eventLocation,
2538
+ event_category: eventCategory,
2539
+ event_sub_category: eventSubCategory || null,
2540
+ event_action: eventAction,
2541
+ event_sub_action: eventSubAction || null,
2542
+ event_details: enrichedEventDetails
2543
+ };
2544
+ logger.debug("Sending partner telemetry event:", partnerEvent);
2545
+ const base = this.partnerApiBaseUrl || this.apiBaseUrl;
2546
+ const telemetryUrl = `${base}/api/v1/partners/analytics/events`;
2547
+ const response = await fetch(telemetryUrl, {
2548
+ method: "POST",
2549
+ headers: {
2550
+ "Content-Type": "application/json",
2551
+ "x-api-key": this.partnerApiKey
2552
+ },
2553
+ body: JSON.stringify(partnerEvent)
2554
+ });
2555
+ if (response.ok) {
2556
+ logger.info("Partner telemetry event sent successfully:", response.status);
2557
+ return true;
2558
+ } else {
2559
+ const errorText = await response.text();
2560
+ logger.error(
2561
+ "Failed to send partner telemetry event:",
2562
+ response.status,
2563
+ errorText
2564
+ );
2565
+ return false;
2566
+ }
2567
+ } catch (error) {
2568
+ logger.error("Error sending partner telemetry event:", error);
2569
+ return false;
2570
+ }
2571
+ }
2572
+ /**
2573
+ * Seeds the CrazyGames user id used for telemetry attribution and registers
2574
+ * an auth listener so the id updates if a guest logs in mid-session.
2575
+ * The id is client-asserted (spoofable) and used only as an attribution label.
2576
+ */
2577
+ async seedCrazyGamesUser() {
2578
+ if (!this.crazyGamesService) return;
2579
+ if (!this.crazyGamesService.isUserAccountAvailable()) {
2580
+ logger.info("CrazyGames account system unavailable \u2014 telemetry attributed by session only");
2581
+ return;
2582
+ }
2583
+ const user = await this.crazyGamesService.getUser();
2584
+ this.crazyGamesUserId = user?.__dangerousUserId ?? null;
2585
+ if (this.crazyGamesUserId) {
2586
+ logger.info("CrazyGames user id seeded for telemetry attribution");
2587
+ }
2588
+ this.crazyGamesService.addAuthListener((updatedUser) => {
2589
+ this.crazyGamesUserId = updatedUser?.__dangerousUserId ?? null;
2590
+ logger.info("CrazyGames auth state changed; telemetry user id updated");
2591
+ });
2592
+ }
2247
2593
  /**
2248
2594
  * Required lifecycle telemetry — Session start.
2249
2595
  * See https://docs.hyve.gg/docs/telemetry#required-lifecycle-events
@@ -2464,12 +2810,28 @@ var HyveClient = class {
2464
2810
  logger.info("Client reset with new sessionId:", this.sessionId);
2465
2811
  }
2466
2812
  /**
2467
- * Get the storage adapter based on mode
2813
+ * Get the storage adapter based on mode.
2814
+ *
2815
+ * Selection order:
2816
+ * 1. An explicit `mode` override ('cloud' | 'local') always wins.
2817
+ * 2. On the CrazyGames platform, the CrazyGames data store is auto-selected
2818
+ * (D3 — public storageMode type is preserved; this is chosen internally).
2819
+ * 3. Otherwise the configured storageMode is used.
2820
+ *
2821
+ * Awaits CrazyGames SDK initialization so the data store is ready before use.
2468
2822
  * @param mode Storage mode override (cloud or local)
2469
2823
  */
2470
- getStorageAdapter(mode) {
2471
- const storageMode = mode || this.storageMode;
2472
- return storageMode === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2824
+ async getStorageAdapter(mode) {
2825
+ if (mode) {
2826
+ return mode === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2827
+ }
2828
+ if (this.crazyGamesService && this.crazyGamesStorageAdapter) {
2829
+ if (this.crazyGamesInitPromise) await this.crazyGamesInitPromise;
2830
+ if (this.crazyGamesService.getEnvironment() === "crazygames") {
2831
+ return this.crazyGamesStorageAdapter;
2832
+ }
2833
+ }
2834
+ return this.storageMode === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2473
2835
  }
2474
2836
  /**
2475
2837
  * Returns the current game ID or throws if not available.
@@ -2493,7 +2855,7 @@ var HyveClient = class {
2493
2855
  const gameId = this.requireGameId();
2494
2856
  const storageMode = storage || this.storageMode;
2495
2857
  logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
2496
- const adapter = this.getStorageAdapter(storage);
2858
+ const adapter = await this.getStorageAdapter(storage);
2497
2859
  const response = await adapter.saveGameData(gameId, key, value, operation, path);
2498
2860
  logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
2499
2861
  return response;
@@ -2508,7 +2870,7 @@ var HyveClient = class {
2508
2870
  const gameId = this.requireGameId();
2509
2871
  const storageMode = storage || this.storageMode;
2510
2872
  logger.debug(`Batch saving ${items.length} game data entries to ${storageMode} for game: ${gameId}`);
2511
- const adapter = this.getStorageAdapter(storage);
2873
+ const adapter = await this.getStorageAdapter(storage);
2512
2874
  const response = await adapter.batchSaveGameData(gameId, items);
2513
2875
  logger.info(`Batch saved ${items.length} game data entries successfully to ${storageMode}`);
2514
2876
  return response;
@@ -2523,7 +2885,7 @@ var HyveClient = class {
2523
2885
  const gameId = this.requireGameId();
2524
2886
  const storageMode = storage || this.storageMode;
2525
2887
  logger.debug(`Getting game data from ${storageMode}: ${gameId}/${key}`);
2526
- const adapter = this.getStorageAdapter(storage);
2888
+ const adapter = await this.getStorageAdapter(storage);
2527
2889
  const data = await adapter.getGameData(gameId, key);
2528
2890
  if (data) {
2529
2891
  logger.info(`Game data retrieved successfully from ${storageMode}: ${gameId}/${key}`);
@@ -2542,7 +2904,7 @@ var HyveClient = class {
2542
2904
  const gameId = this.requireGameId();
2543
2905
  const storageMode = storage || this.storageMode;
2544
2906
  logger.debug(`Getting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
2545
- const adapter = this.getStorageAdapter(storage);
2907
+ const adapter = await this.getStorageAdapter(storage);
2546
2908
  const data = await adapter.getMultipleGameData(gameId, keys);
2547
2909
  logger.info(`Retrieved ${data.length} game data entries from ${storageMode}`);
2548
2910
  return data;
@@ -2557,7 +2919,7 @@ var HyveClient = class {
2557
2919
  const gameId = this.requireGameId();
2558
2920
  const storageMode = storage || this.storageMode;
2559
2921
  logger.debug(`Deleting game data from ${storageMode}: ${gameId}/${key}`);
2560
- const adapter = this.getStorageAdapter(storage);
2922
+ const adapter = await this.getStorageAdapter(storage);
2561
2923
  const deleted = await adapter.deleteGameData(gameId, key);
2562
2924
  if (deleted) {
2563
2925
  logger.info(`Game data deleted successfully from ${storageMode}: ${gameId}/${key}`);
@@ -2576,7 +2938,7 @@ var HyveClient = class {
2576
2938
  const gameId = this.requireGameId();
2577
2939
  const storageMode = storage || this.storageMode;
2578
2940
  logger.debug(`Deleting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
2579
- const adapter = this.getStorageAdapter(storage);
2941
+ const adapter = await this.getStorageAdapter(storage);
2580
2942
  const deletedCount = await adapter.deleteMultipleGameData(gameId, keys);
2581
2943
  logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
2582
2944
  return deletedCount;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyve-sdk/js",
3
- "version": "2.13.0",
3
+ "version": "2.14.0-canary.0",
4
4
  "description": "Hyve SDK - TypeScript wrapper for Hyve game server integration",
5
5
  "private": false,
6
6
  "publishConfig": {