@hyve-sdk/js 2.14.1 → 2.14.2

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
@@ -131,6 +131,21 @@ console.log(hyve.getStorageMode()); // "cloud"
131
131
  | `cloud` | Synced to backend API (default) |
132
132
  | `local` | Browser `localStorage`, device-only |
133
133
 
134
+ On partner platforms (e.g. CrazyGames) the SDK transparently routes storage to that platform's own data store regardless of `mode`, since the Hyve cloud backend isn't reachable there.
135
+
136
+ ### Checking storage availability
137
+
138
+ Do **not** gate saving on `isUserAuthenticated()` — it only reflects a Hyve JWT and is always `false` on CrazyGames, whose data store needs no Hyve login (it even works for guests). Gating on auth silently disables all saving there. Use `isStorageAvailable()`, which reports whether a save will actually persist for the active backend:
139
+
140
+ ```ts
141
+ // Correct gate — awaits platform init, accounts for CrazyGames / cloud / local
142
+ if (await hyve.isStorageAvailable()) {
143
+ await hyve.saveGameData("player_level", 5);
144
+ }
145
+ ```
146
+
147
+ `isStorageAvailable()` is true when: on CrazyGames the data store is ready (SDK initialized and the "Progress Save" toggle is enabled for the submission); in `cloud` mode a Hyve JWT is present; in `local` mode always (browser `localStorage`).
148
+
134
149
  ## Leaderboards
135
150
 
136
151
  Rank players by numeric values stored in persistent game data.
@@ -426,6 +441,7 @@ new HyveClient(config?: {
426
441
  | `deleteGameData(key, storage?)` | `Promise<boolean>` | Delete a single value |
427
442
  | `deleteMultipleGameData(keys, storage?)` | `Promise<number>` | Delete multiple values; returns count |
428
443
  | `getGameDataLeaderboard(params)` | `Promise<GameDataLeaderboardResponse>` | Fetch players ranked by a game data key |
444
+ | `isStorageAvailable(mode?)` | `Promise<boolean>` | Whether a save will actually persist on the active backend; use this to gate saving, not `isUserAuthenticated()` |
429
445
  | `configureStorage(mode)` | `void` | Set default storage mode |
430
446
  | `getStorageMode()` | `"cloud" \| "local"` | Get current storage mode |
431
447
 
package/dist/index.d.mts CHANGED
@@ -716,7 +716,12 @@ declare class HyveClient {
716
716
  */
717
717
  getApiBaseUrl(): string;
718
718
  /**
719
- * Checks if user is authenticated
719
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
720
+ *
721
+ * Do NOT use this to gate persistent storage — it is always false on partner
722
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
723
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
724
+ * for genuinely auth-only concerns (login UI, cloud-only features).
720
725
  * @returns Boolean indicating authentication status
721
726
  */
722
727
  isUserAuthenticated(): boolean;
@@ -750,6 +755,28 @@ declare class HyveClient {
750
755
  * @param mode Storage mode override (cloud or local)
751
756
  */
752
757
  private getStorageAdapter;
758
+ /**
759
+ * Reports whether persistent storage is usable right now — i.e. whether a
760
+ * subsequent saveGameData / getGameData call will actually persist.
761
+ *
762
+ * This is the correct gate for "should I save progress?" — NOT
763
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
764
+ * on partner platforms like CrazyGames even though their own data store works
765
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
766
+ * silently disable all saving on CrazyGames.
767
+ *
768
+ * Resolves the active backend for the given mode and checks its real
769
+ * requirement:
770
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
771
+ * "Progress Save" toggle is enabled for the submission).
772
+ * - cloud: a Hyve JWT is present (the backend API requires it).
773
+ * - local: always available in a browser.
774
+ *
775
+ * Awaits platform SDK initialization so the answer is correct on first paint.
776
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
777
+ * @returns Promise resolving to whether storage will persist
778
+ */
779
+ isStorageAvailable(mode?: 'cloud' | 'local'): Promise<boolean>;
753
780
  /**
754
781
  * Returns the current game ID or throws if not available.
755
782
  */
@@ -1095,6 +1122,14 @@ declare class CrazyGamesService {
1095
1122
  * auto-select the CrazyGames storage adapter.
1096
1123
  */
1097
1124
  getEnvironment(): CrazyGamesEnvironment | null;
1125
+ /**
1126
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1127
+ * initialized and the "Progress Save" toggle is enabled for this submission
1128
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1129
+ * would throw, so callers should treat persistent storage as unavailable.
1130
+ * Note: this is independent of login — the data store works for guests too.
1131
+ */
1132
+ isDataAvailable(): boolean;
1098
1133
  /**
1099
1134
  * Whether the CrazyGames account system is present (sync). When false,
1100
1135
  * there is no logged-in user concept and telemetry falls back to guests.
package/dist/index.d.ts CHANGED
@@ -716,7 +716,12 @@ declare class HyveClient {
716
716
  */
717
717
  getApiBaseUrl(): string;
718
718
  /**
719
- * Checks if user is authenticated
719
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
720
+ *
721
+ * Do NOT use this to gate persistent storage — it is always false on partner
722
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
723
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
724
+ * for genuinely auth-only concerns (login UI, cloud-only features).
720
725
  * @returns Boolean indicating authentication status
721
726
  */
722
727
  isUserAuthenticated(): boolean;
@@ -750,6 +755,28 @@ declare class HyveClient {
750
755
  * @param mode Storage mode override (cloud or local)
751
756
  */
752
757
  private getStorageAdapter;
758
+ /**
759
+ * Reports whether persistent storage is usable right now — i.e. whether a
760
+ * subsequent saveGameData / getGameData call will actually persist.
761
+ *
762
+ * This is the correct gate for "should I save progress?" — NOT
763
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
764
+ * on partner platforms like CrazyGames even though their own data store works
765
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
766
+ * silently disable all saving on CrazyGames.
767
+ *
768
+ * Resolves the active backend for the given mode and checks its real
769
+ * requirement:
770
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
771
+ * "Progress Save" toggle is enabled for the submission).
772
+ * - cloud: a Hyve JWT is present (the backend API requires it).
773
+ * - local: always available in a browser.
774
+ *
775
+ * Awaits platform SDK initialization so the answer is correct on first paint.
776
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
777
+ * @returns Promise resolving to whether storage will persist
778
+ */
779
+ isStorageAvailable(mode?: 'cloud' | 'local'): Promise<boolean>;
753
780
  /**
754
781
  * Returns the current game ID or throws if not available.
755
782
  */
@@ -1095,6 +1122,14 @@ declare class CrazyGamesService {
1095
1122
  * auto-select the CrazyGames storage adapter.
1096
1123
  */
1097
1124
  getEnvironment(): CrazyGamesEnvironment | null;
1125
+ /**
1126
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1127
+ * initialized and the "Progress Save" toggle is enabled for this submission
1128
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1129
+ * would throw, so callers should treat persistent storage as unavailable.
1130
+ * Note: this is independent of login — the data store works for guests too.
1131
+ */
1132
+ isDataAvailable(): boolean;
1098
1133
  /**
1099
1134
  * Whether the CrazyGames account system is present (sync). When false,
1100
1135
  * there is no logged-in user concept and telemetry falls back to guests.
package/dist/index.js CHANGED
@@ -1430,6 +1430,16 @@ var CrazyGamesService = class {
1430
1430
  getEnvironment() {
1431
1431
  return this.environment;
1432
1432
  }
1433
+ /**
1434
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1435
+ * initialized and the "Progress Save" toggle is enabled for this submission
1436
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1437
+ * would throw, so callers should treat persistent storage as unavailable.
1438
+ * Note: this is independent of login — the data store works for guests too.
1439
+ */
1440
+ isDataAvailable() {
1441
+ return this.initialized && !!window.CrazyGames?.SDK.data;
1442
+ }
1433
1443
  /**
1434
1444
  * Whether the CrazyGames account system is present (sync). When false,
1435
1445
  * there is no logged-in user concept and telemetry falls back to guests.
@@ -2884,7 +2894,12 @@ var HyveClient = class {
2884
2894
  return this.apiBaseUrl;
2885
2895
  }
2886
2896
  /**
2887
- * Checks if user is authenticated
2897
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
2898
+ *
2899
+ * Do NOT use this to gate persistent storage — it is always false on partner
2900
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
2901
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
2902
+ * for genuinely auth-only concerns (login UI, cloud-only features).
2888
2903
  * @returns Boolean indicating authentication status
2889
2904
  */
2890
2905
  isUserAuthenticated() {
@@ -2945,6 +2960,41 @@ var HyveClient = class {
2945
2960
  const selected = mode ?? this.storageMode;
2946
2961
  return selected === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2947
2962
  }
2963
+ /**
2964
+ * Reports whether persistent storage is usable right now — i.e. whether a
2965
+ * subsequent saveGameData / getGameData call will actually persist.
2966
+ *
2967
+ * This is the correct gate for "should I save progress?" — NOT
2968
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
2969
+ * on partner platforms like CrazyGames even though their own data store works
2970
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
2971
+ * silently disable all saving on CrazyGames.
2972
+ *
2973
+ * Resolves the active backend for the given mode and checks its real
2974
+ * requirement:
2975
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
2976
+ * "Progress Save" toggle is enabled for the submission).
2977
+ * - cloud: a Hyve JWT is present (the backend API requires it).
2978
+ * - local: always available in a browser.
2979
+ *
2980
+ * Awaits platform SDK initialization so the answer is correct on first paint.
2981
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
2982
+ * @returns Promise resolving to whether storage will persist
2983
+ */
2984
+ async isStorageAvailable(mode) {
2985
+ if (this.crazyGamesService && this.crazyGamesStorageAdapter) {
2986
+ if (this.crazyGamesInitPromise) await this.crazyGamesInitPromise;
2987
+ const env = this.crazyGamesService.getEnvironment();
2988
+ if (env === "crazygames" || env === "local") {
2989
+ return this.crazyGamesService.isDataAvailable();
2990
+ }
2991
+ }
2992
+ const selected = mode ?? this.storageMode;
2993
+ if (selected === "local") {
2994
+ return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
2995
+ }
2996
+ return this.jwtToken !== null;
2997
+ }
2948
2998
  /**
2949
2999
  * Returns the current game ID or throws if not available.
2950
3000
  */
package/dist/index.mjs CHANGED
@@ -1389,6 +1389,16 @@ var CrazyGamesService = class {
1389
1389
  getEnvironment() {
1390
1390
  return this.environment;
1391
1391
  }
1392
+ /**
1393
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1394
+ * initialized and the "Progress Save" toggle is enabled for this submission
1395
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1396
+ * would throw, so callers should treat persistent storage as unavailable.
1397
+ * Note: this is independent of login — the data store works for guests too.
1398
+ */
1399
+ isDataAvailable() {
1400
+ return this.initialized && !!window.CrazyGames?.SDK.data;
1401
+ }
1392
1402
  /**
1393
1403
  * Whether the CrazyGames account system is present (sync). When false,
1394
1404
  * there is no logged-in user concept and telemetry falls back to guests.
@@ -2843,7 +2853,12 @@ var HyveClient = class {
2843
2853
  return this.apiBaseUrl;
2844
2854
  }
2845
2855
  /**
2846
- * Checks if user is authenticated
2856
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
2857
+ *
2858
+ * Do NOT use this to gate persistent storage — it is always false on partner
2859
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
2860
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
2861
+ * for genuinely auth-only concerns (login UI, cloud-only features).
2847
2862
  * @returns Boolean indicating authentication status
2848
2863
  */
2849
2864
  isUserAuthenticated() {
@@ -2904,6 +2919,41 @@ var HyveClient = class {
2904
2919
  const selected = mode ?? this.storageMode;
2905
2920
  return selected === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2906
2921
  }
2922
+ /**
2923
+ * Reports whether persistent storage is usable right now — i.e. whether a
2924
+ * subsequent saveGameData / getGameData call will actually persist.
2925
+ *
2926
+ * This is the correct gate for "should I save progress?" — NOT
2927
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
2928
+ * on partner platforms like CrazyGames even though their own data store works
2929
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
2930
+ * silently disable all saving on CrazyGames.
2931
+ *
2932
+ * Resolves the active backend for the given mode and checks its real
2933
+ * requirement:
2934
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
2935
+ * "Progress Save" toggle is enabled for the submission).
2936
+ * - cloud: a Hyve JWT is present (the backend API requires it).
2937
+ * - local: always available in a browser.
2938
+ *
2939
+ * Awaits platform SDK initialization so the answer is correct on first paint.
2940
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
2941
+ * @returns Promise resolving to whether storage will persist
2942
+ */
2943
+ async isStorageAvailable(mode) {
2944
+ if (this.crazyGamesService && this.crazyGamesStorageAdapter) {
2945
+ if (this.crazyGamesInitPromise) await this.crazyGamesInitPromise;
2946
+ const env = this.crazyGamesService.getEnvironment();
2947
+ if (env === "crazygames" || env === "local") {
2948
+ return this.crazyGamesService.isDataAvailable();
2949
+ }
2950
+ }
2951
+ const selected = mode ?? this.storageMode;
2952
+ if (selected === "local") {
2953
+ return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
2954
+ }
2955
+ return this.jwtToken !== null;
2956
+ }
2907
2957
  /**
2908
2958
  * Returns the current game ID or throws if not available.
2909
2959
  */
package/dist/react.d.mts CHANGED
@@ -447,7 +447,12 @@ declare class HyveClient {
447
447
  */
448
448
  getApiBaseUrl(): string;
449
449
  /**
450
- * Checks if user is authenticated
450
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
451
+ *
452
+ * Do NOT use this to gate persistent storage — it is always false on partner
453
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
454
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
455
+ * for genuinely auth-only concerns (login UI, cloud-only features).
451
456
  * @returns Boolean indicating authentication status
452
457
  */
453
458
  isUserAuthenticated(): boolean;
@@ -481,6 +486,28 @@ declare class HyveClient {
481
486
  * @param mode Storage mode override (cloud or local)
482
487
  */
483
488
  private getStorageAdapter;
489
+ /**
490
+ * Reports whether persistent storage is usable right now — i.e. whether a
491
+ * subsequent saveGameData / getGameData call will actually persist.
492
+ *
493
+ * This is the correct gate for "should I save progress?" — NOT
494
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
495
+ * on partner platforms like CrazyGames even though their own data store works
496
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
497
+ * silently disable all saving on CrazyGames.
498
+ *
499
+ * Resolves the active backend for the given mode and checks its real
500
+ * requirement:
501
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
502
+ * "Progress Save" toggle is enabled for the submission).
503
+ * - cloud: a Hyve JWT is present (the backend API requires it).
504
+ * - local: always available in a browser.
505
+ *
506
+ * Awaits platform SDK initialization so the answer is correct on first paint.
507
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
508
+ * @returns Promise resolving to whether storage will persist
509
+ */
510
+ isStorageAvailable(mode?: 'cloud' | 'local'): Promise<boolean>;
484
511
  /**
485
512
  * Returns the current game ID or throws if not available.
486
513
  */
package/dist/react.d.ts CHANGED
@@ -447,7 +447,12 @@ declare class HyveClient {
447
447
  */
448
448
  getApiBaseUrl(): string;
449
449
  /**
450
- * Checks if user is authenticated
450
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
451
+ *
452
+ * Do NOT use this to gate persistent storage — it is always false on partner
453
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
454
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
455
+ * for genuinely auth-only concerns (login UI, cloud-only features).
451
456
  * @returns Boolean indicating authentication status
452
457
  */
453
458
  isUserAuthenticated(): boolean;
@@ -481,6 +486,28 @@ declare class HyveClient {
481
486
  * @param mode Storage mode override (cloud or local)
482
487
  */
483
488
  private getStorageAdapter;
489
+ /**
490
+ * Reports whether persistent storage is usable right now — i.e. whether a
491
+ * subsequent saveGameData / getGameData call will actually persist.
492
+ *
493
+ * This is the correct gate for "should I save progress?" — NOT
494
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
495
+ * on partner platforms like CrazyGames even though their own data store works
496
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
497
+ * silently disable all saving on CrazyGames.
498
+ *
499
+ * Resolves the active backend for the given mode and checks its real
500
+ * requirement:
501
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
502
+ * "Progress Save" toggle is enabled for the submission).
503
+ * - cloud: a Hyve JWT is present (the backend API requires it).
504
+ * - local: always available in a browser.
505
+ *
506
+ * Awaits platform SDK initialization so the answer is correct on first paint.
507
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
508
+ * @returns Promise resolving to whether storage will persist
509
+ */
510
+ isStorageAvailable(mode?: 'cloud' | 'local'): Promise<boolean>;
484
511
  /**
485
512
  * Returns the current game ID or throws if not available.
486
513
  */
package/dist/react.js CHANGED
@@ -1387,6 +1387,16 @@ var CrazyGamesService = class {
1387
1387
  getEnvironment() {
1388
1388
  return this.environment;
1389
1389
  }
1390
+ /**
1391
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1392
+ * initialized and the "Progress Save" toggle is enabled for this submission
1393
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1394
+ * would throw, so callers should treat persistent storage as unavailable.
1395
+ * Note: this is independent of login — the data store works for guests too.
1396
+ */
1397
+ isDataAvailable() {
1398
+ return this.initialized && !!window.CrazyGames?.SDK.data;
1399
+ }
1390
1400
  /**
1391
1401
  * Whether the CrazyGames account system is present (sync). When false,
1392
1402
  * there is no logged-in user concept and telemetry falls back to guests.
@@ -2835,7 +2845,12 @@ var HyveClient = class {
2835
2845
  return this.apiBaseUrl;
2836
2846
  }
2837
2847
  /**
2838
- * Checks if user is authenticated
2848
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
2849
+ *
2850
+ * Do NOT use this to gate persistent storage — it is always false on partner
2851
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
2852
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
2853
+ * for genuinely auth-only concerns (login UI, cloud-only features).
2839
2854
  * @returns Boolean indicating authentication status
2840
2855
  */
2841
2856
  isUserAuthenticated() {
@@ -2896,6 +2911,41 @@ var HyveClient = class {
2896
2911
  const selected = mode ?? this.storageMode;
2897
2912
  return selected === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2898
2913
  }
2914
+ /**
2915
+ * Reports whether persistent storage is usable right now — i.e. whether a
2916
+ * subsequent saveGameData / getGameData call will actually persist.
2917
+ *
2918
+ * This is the correct gate for "should I save progress?" — NOT
2919
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
2920
+ * on partner platforms like CrazyGames even though their own data store works
2921
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
2922
+ * silently disable all saving on CrazyGames.
2923
+ *
2924
+ * Resolves the active backend for the given mode and checks its real
2925
+ * requirement:
2926
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
2927
+ * "Progress Save" toggle is enabled for the submission).
2928
+ * - cloud: a Hyve JWT is present (the backend API requires it).
2929
+ * - local: always available in a browser.
2930
+ *
2931
+ * Awaits platform SDK initialization so the answer is correct on first paint.
2932
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
2933
+ * @returns Promise resolving to whether storage will persist
2934
+ */
2935
+ async isStorageAvailable(mode) {
2936
+ if (this.crazyGamesService && this.crazyGamesStorageAdapter) {
2937
+ if (this.crazyGamesInitPromise) await this.crazyGamesInitPromise;
2938
+ const env = this.crazyGamesService.getEnvironment();
2939
+ if (env === "crazygames" || env === "local") {
2940
+ return this.crazyGamesService.isDataAvailable();
2941
+ }
2942
+ }
2943
+ const selected = mode ?? this.storageMode;
2944
+ if (selected === "local") {
2945
+ return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
2946
+ }
2947
+ return this.jwtToken !== null;
2948
+ }
2899
2949
  /**
2900
2950
  * Returns the current game ID or throws if not available.
2901
2951
  */
package/dist/react.mjs CHANGED
@@ -1365,6 +1365,16 @@ var CrazyGamesService = class {
1365
1365
  getEnvironment() {
1366
1366
  return this.environment;
1367
1367
  }
1368
+ /**
1369
+ * Whether the persistent data store is usable right now — i.e. the SDK has
1370
+ * initialized and the "Progress Save" toggle is enabled for this submission
1371
+ * (the `data` module is absent otherwise). When false, dataGetItem/dataSetItem
1372
+ * would throw, so callers should treat persistent storage as unavailable.
1373
+ * Note: this is independent of login — the data store works for guests too.
1374
+ */
1375
+ isDataAvailable() {
1376
+ return this.initialized && !!window.CrazyGames?.SDK.data;
1377
+ }
1368
1378
  /**
1369
1379
  * Whether the CrazyGames account system is present (sync). When false,
1370
1380
  * there is no logged-in user concept and telemetry falls back to guests.
@@ -2813,7 +2823,12 @@ var HyveClient = class {
2813
2823
  return this.apiBaseUrl;
2814
2824
  }
2815
2825
  /**
2816
- * Checks if user is authenticated
2826
+ * Checks if a Hyve user is authenticated (a Hyve JWT was decoded).
2827
+ *
2828
+ * Do NOT use this to gate persistent storage — it is always false on partner
2829
+ * platforms like CrazyGames, whose data store needs no Hyve JWT. Use
2830
+ * {@link isStorageAvailable} for "can I save progress?" instead. Reserve this
2831
+ * for genuinely auth-only concerns (login UI, cloud-only features).
2817
2832
  * @returns Boolean indicating authentication status
2818
2833
  */
2819
2834
  isUserAuthenticated() {
@@ -2874,6 +2889,41 @@ var HyveClient = class {
2874
2889
  const selected = mode ?? this.storageMode;
2875
2890
  return selected === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
2876
2891
  }
2892
+ /**
2893
+ * Reports whether persistent storage is usable right now — i.e. whether a
2894
+ * subsequent saveGameData / getGameData call will actually persist.
2895
+ *
2896
+ * This is the correct gate for "should I save progress?" — NOT
2897
+ * isUserAuthenticated(), which only reflects a Hyve JWT and is always false
2898
+ * on partner platforms like CrazyGames even though their own data store works
2899
+ * fine (and works for guests). Gating storage on isUserAuthenticated() will
2900
+ * silently disable all saving on CrazyGames.
2901
+ *
2902
+ * Resolves the active backend for the given mode and checks its real
2903
+ * requirement:
2904
+ * - CrazyGames: the CrazyGames data store is ready (SDK initialized and the
2905
+ * "Progress Save" toggle is enabled for the submission).
2906
+ * - cloud: a Hyve JWT is present (the backend API requires it).
2907
+ * - local: always available in a browser.
2908
+ *
2909
+ * Awaits platform SDK initialization so the answer is correct on first paint.
2910
+ * @param mode Storage mode override ('cloud' or 'local'); ignored on CrazyGames
2911
+ * @returns Promise resolving to whether storage will persist
2912
+ */
2913
+ async isStorageAvailable(mode) {
2914
+ if (this.crazyGamesService && this.crazyGamesStorageAdapter) {
2915
+ if (this.crazyGamesInitPromise) await this.crazyGamesInitPromise;
2916
+ const env = this.crazyGamesService.getEnvironment();
2917
+ if (env === "crazygames" || env === "local") {
2918
+ return this.crazyGamesService.isDataAvailable();
2919
+ }
2920
+ }
2921
+ const selected = mode ?? this.storageMode;
2922
+ if (selected === "local") {
2923
+ return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
2924
+ }
2925
+ return this.jwtToken !== null;
2926
+ }
2877
2927
  /**
2878
2928
  * Returns the current game ID or throws if not available.
2879
2929
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyve-sdk/js",
3
- "version": "2.14.1",
3
+ "version": "2.14.2",
4
4
  "description": "Hyve SDK - TypeScript wrapper for Hyve game server integration",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -69,8 +69,8 @@
69
69
  "tsup": "^8.4.0",
70
70
  "typescript": "^5.3.3",
71
71
  "vitest": "^4.1.8",
72
- "@repo/eslint-config": "0.0.0",
73
- "@repo/typescript-config": "0.0.0"
72
+ "@repo/typescript-config": "0.0.0",
73
+ "@repo/eslint-config": "0.0.0"
74
74
  },
75
75
  "scripts": {
76
76
  "lint": "eslint . --max-warnings 0",