@hyve-sdk/js 1.3.6 → 1.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/dist/index.d.mts +142 -1
- package/dist/index.d.ts +142 -1
- package/dist/index.js +297 -2
- package/dist/index.mjs +295 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -83,6 +83,43 @@ interface AdConfig$1 {
|
|
|
83
83
|
/** Callback when user earns a reward (rewarded ads only) */
|
|
84
84
|
onRewardEarned?: () => void;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Persistent Game Data Types
|
|
88
|
+
*/
|
|
89
|
+
/** Generic value type for game data storage - can be any JSON-serializable value */
|
|
90
|
+
type GameDataValue = string | number | boolean | null | GameDataValue[] | {
|
|
91
|
+
[key: string]: GameDataValue;
|
|
92
|
+
};
|
|
93
|
+
/** Single game data item with metadata */
|
|
94
|
+
interface GameDataItem {
|
|
95
|
+
key: string;
|
|
96
|
+
value: GameDataValue;
|
|
97
|
+
created_at: string;
|
|
98
|
+
updated_at: string;
|
|
99
|
+
}
|
|
100
|
+
/** Response from save operations */
|
|
101
|
+
interface SaveGameDataResponse {
|
|
102
|
+
success: boolean;
|
|
103
|
+
message: string;
|
|
104
|
+
}
|
|
105
|
+
/** Response when getting a single game data entry */
|
|
106
|
+
interface GetGameDataResponse {
|
|
107
|
+
data: GameDataItem;
|
|
108
|
+
}
|
|
109
|
+
/** Response when getting multiple game data entries */
|
|
110
|
+
interface GetGameDataBatchResponse {
|
|
111
|
+
data: GameDataItem[];
|
|
112
|
+
}
|
|
113
|
+
/** Response after deleting game data */
|
|
114
|
+
interface DeleteGameDataResponse {
|
|
115
|
+
success: boolean;
|
|
116
|
+
deleted_count: number;
|
|
117
|
+
}
|
|
118
|
+
/** Batch item for saving multiple entries */
|
|
119
|
+
interface GameDataBatchItem {
|
|
120
|
+
key: string;
|
|
121
|
+
value: GameDataValue;
|
|
122
|
+
}
|
|
86
123
|
|
|
87
124
|
/**
|
|
88
125
|
* Ads Service for Hyve SDK
|
|
@@ -392,6 +429,8 @@ interface HyveClientConfig extends TelemetryConfig {
|
|
|
392
429
|
ads?: AdConfig$1;
|
|
393
430
|
/** Billing configuration (disabled by default) */
|
|
394
431
|
billing?: BillingConfig;
|
|
432
|
+
/** Storage mode for persistent game data - 'cloud' (default) or 'local' */
|
|
433
|
+
storageMode?: 'cloud' | 'local';
|
|
395
434
|
}
|
|
396
435
|
/**
|
|
397
436
|
* HyveClient provides telemetry and authentication functionality for Hyve games
|
|
@@ -407,6 +446,9 @@ declare class HyveClient {
|
|
|
407
446
|
private billingService;
|
|
408
447
|
private billingConfig;
|
|
409
448
|
private billingCallbacks;
|
|
449
|
+
private storageMode;
|
|
450
|
+
private cloudStorageAdapter;
|
|
451
|
+
private localStorageAdapter;
|
|
410
452
|
/**
|
|
411
453
|
* Creates a new HyveClient instance
|
|
412
454
|
* @param config Optional configuration including telemetry and ads
|
|
@@ -497,6 +539,64 @@ declare class HyveClient {
|
|
|
497
539
|
* Resets the client state
|
|
498
540
|
*/
|
|
499
541
|
reset(): void;
|
|
542
|
+
/**
|
|
543
|
+
* Get the storage adapter based on mode
|
|
544
|
+
* @param mode Storage mode override (cloud or local)
|
|
545
|
+
*/
|
|
546
|
+
private getStorageAdapter;
|
|
547
|
+
/**
|
|
548
|
+
* Save persistent game data
|
|
549
|
+
* @param key Data key
|
|
550
|
+
* @param value Data value (any JSON-serializable value)
|
|
551
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
552
|
+
* @returns Promise resolving to save response
|
|
553
|
+
*/
|
|
554
|
+
saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
|
|
555
|
+
/**
|
|
556
|
+
* Batch save persistent game data
|
|
557
|
+
* @param items Array of key-value pairs to save
|
|
558
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
559
|
+
* @returns Promise resolving to save response
|
|
560
|
+
*/
|
|
561
|
+
batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
|
|
562
|
+
/**
|
|
563
|
+
* Get persistent game data
|
|
564
|
+
* @param key Data key
|
|
565
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
566
|
+
* @returns Promise resolving to game data item or null if not found
|
|
567
|
+
*/
|
|
568
|
+
getGameData(key: string, storage?: 'cloud' | 'local'): Promise<GameDataItem | null>;
|
|
569
|
+
/**
|
|
570
|
+
* Get multiple persistent game data entries
|
|
571
|
+
* @param keys Array of data keys
|
|
572
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
573
|
+
* @returns Promise resolving to array of game data items
|
|
574
|
+
*/
|
|
575
|
+
getMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<GameDataItem[]>;
|
|
576
|
+
/**
|
|
577
|
+
* Delete persistent game data
|
|
578
|
+
* @param key Data key
|
|
579
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
580
|
+
* @returns Promise resolving to boolean indicating if data was deleted
|
|
581
|
+
*/
|
|
582
|
+
deleteGameData(key: string, storage?: 'cloud' | 'local'): Promise<boolean>;
|
|
583
|
+
/**
|
|
584
|
+
* Delete multiple persistent game data entries
|
|
585
|
+
* @param keys Array of data keys
|
|
586
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
587
|
+
* @returns Promise resolving to number of entries deleted
|
|
588
|
+
*/
|
|
589
|
+
deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
|
|
590
|
+
/**
|
|
591
|
+
* Configure storage mode
|
|
592
|
+
* @param mode Storage mode ('cloud' or 'local')
|
|
593
|
+
*/
|
|
594
|
+
configureStorage(mode: 'cloud' | 'local'): void;
|
|
595
|
+
/**
|
|
596
|
+
* Get current storage mode
|
|
597
|
+
* @returns Current storage mode
|
|
598
|
+
*/
|
|
599
|
+
getStorageMode(): 'cloud' | 'local';
|
|
500
600
|
/**
|
|
501
601
|
* Configure ads service
|
|
502
602
|
* @param config Ads configuration
|
|
@@ -574,6 +674,47 @@ declare class HyveClient {
|
|
|
574
674
|
onBillingLog(callback: (level: "info" | "warn" | "error", message: string, data?: any) => void): void;
|
|
575
675
|
}
|
|
576
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Storage adapter interface - supports cloud and local implementations
|
|
679
|
+
*/
|
|
680
|
+
interface StorageAdapter {
|
|
681
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
682
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
683
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
684
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
685
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
686
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Cloud storage adapter - stores data via API calls to backend
|
|
690
|
+
*/
|
|
691
|
+
declare class CloudStorageAdapter implements StorageAdapter {
|
|
692
|
+
private callApi;
|
|
693
|
+
constructor(callApi: <T = any>(endpoint: string, options?: RequestInit) => Promise<T>);
|
|
694
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
695
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
696
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
697
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
698
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
699
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Local storage adapter - stores data in browser's localStorage
|
|
703
|
+
* Namespaced by game_id only (device-specific storage)
|
|
704
|
+
*/
|
|
705
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
706
|
+
private getUserId;
|
|
707
|
+
private readonly storagePrefix;
|
|
708
|
+
constructor(getUserId: () => string | null);
|
|
709
|
+
private getStorageKey;
|
|
710
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
711
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
712
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
713
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
714
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
715
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
716
|
+
}
|
|
717
|
+
|
|
577
718
|
/**
|
|
578
719
|
* Logger utility for the Hyve SDK
|
|
579
720
|
* Automatically enabled in development (NODE_ENV !== 'production')
|
|
@@ -847,4 +988,4 @@ declare class NativeBridge {
|
|
|
847
988
|
*/
|
|
848
989
|
declare function generateUUID(): string;
|
|
849
990
|
|
|
850
|
-
export { type AdConfig$1 as AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, type PurchaseResult, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, logger, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };
|
|
991
|
+
export { type AdConfig$1 as AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, logger, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,43 @@ interface AdConfig$1 {
|
|
|
83
83
|
/** Callback when user earns a reward (rewarded ads only) */
|
|
84
84
|
onRewardEarned?: () => void;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Persistent Game Data Types
|
|
88
|
+
*/
|
|
89
|
+
/** Generic value type for game data storage - can be any JSON-serializable value */
|
|
90
|
+
type GameDataValue = string | number | boolean | null | GameDataValue[] | {
|
|
91
|
+
[key: string]: GameDataValue;
|
|
92
|
+
};
|
|
93
|
+
/** Single game data item with metadata */
|
|
94
|
+
interface GameDataItem {
|
|
95
|
+
key: string;
|
|
96
|
+
value: GameDataValue;
|
|
97
|
+
created_at: string;
|
|
98
|
+
updated_at: string;
|
|
99
|
+
}
|
|
100
|
+
/** Response from save operations */
|
|
101
|
+
interface SaveGameDataResponse {
|
|
102
|
+
success: boolean;
|
|
103
|
+
message: string;
|
|
104
|
+
}
|
|
105
|
+
/** Response when getting a single game data entry */
|
|
106
|
+
interface GetGameDataResponse {
|
|
107
|
+
data: GameDataItem;
|
|
108
|
+
}
|
|
109
|
+
/** Response when getting multiple game data entries */
|
|
110
|
+
interface GetGameDataBatchResponse {
|
|
111
|
+
data: GameDataItem[];
|
|
112
|
+
}
|
|
113
|
+
/** Response after deleting game data */
|
|
114
|
+
interface DeleteGameDataResponse {
|
|
115
|
+
success: boolean;
|
|
116
|
+
deleted_count: number;
|
|
117
|
+
}
|
|
118
|
+
/** Batch item for saving multiple entries */
|
|
119
|
+
interface GameDataBatchItem {
|
|
120
|
+
key: string;
|
|
121
|
+
value: GameDataValue;
|
|
122
|
+
}
|
|
86
123
|
|
|
87
124
|
/**
|
|
88
125
|
* Ads Service for Hyve SDK
|
|
@@ -392,6 +429,8 @@ interface HyveClientConfig extends TelemetryConfig {
|
|
|
392
429
|
ads?: AdConfig$1;
|
|
393
430
|
/** Billing configuration (disabled by default) */
|
|
394
431
|
billing?: BillingConfig;
|
|
432
|
+
/** Storage mode for persistent game data - 'cloud' (default) or 'local' */
|
|
433
|
+
storageMode?: 'cloud' | 'local';
|
|
395
434
|
}
|
|
396
435
|
/**
|
|
397
436
|
* HyveClient provides telemetry and authentication functionality for Hyve games
|
|
@@ -407,6 +446,9 @@ declare class HyveClient {
|
|
|
407
446
|
private billingService;
|
|
408
447
|
private billingConfig;
|
|
409
448
|
private billingCallbacks;
|
|
449
|
+
private storageMode;
|
|
450
|
+
private cloudStorageAdapter;
|
|
451
|
+
private localStorageAdapter;
|
|
410
452
|
/**
|
|
411
453
|
* Creates a new HyveClient instance
|
|
412
454
|
* @param config Optional configuration including telemetry and ads
|
|
@@ -497,6 +539,64 @@ declare class HyveClient {
|
|
|
497
539
|
* Resets the client state
|
|
498
540
|
*/
|
|
499
541
|
reset(): void;
|
|
542
|
+
/**
|
|
543
|
+
* Get the storage adapter based on mode
|
|
544
|
+
* @param mode Storage mode override (cloud or local)
|
|
545
|
+
*/
|
|
546
|
+
private getStorageAdapter;
|
|
547
|
+
/**
|
|
548
|
+
* Save persistent game data
|
|
549
|
+
* @param key Data key
|
|
550
|
+
* @param value Data value (any JSON-serializable value)
|
|
551
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
552
|
+
* @returns Promise resolving to save response
|
|
553
|
+
*/
|
|
554
|
+
saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
|
|
555
|
+
/**
|
|
556
|
+
* Batch save persistent game data
|
|
557
|
+
* @param items Array of key-value pairs to save
|
|
558
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
559
|
+
* @returns Promise resolving to save response
|
|
560
|
+
*/
|
|
561
|
+
batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
|
|
562
|
+
/**
|
|
563
|
+
* Get persistent game data
|
|
564
|
+
* @param key Data key
|
|
565
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
566
|
+
* @returns Promise resolving to game data item or null if not found
|
|
567
|
+
*/
|
|
568
|
+
getGameData(key: string, storage?: 'cloud' | 'local'): Promise<GameDataItem | null>;
|
|
569
|
+
/**
|
|
570
|
+
* Get multiple persistent game data entries
|
|
571
|
+
* @param keys Array of data keys
|
|
572
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
573
|
+
* @returns Promise resolving to array of game data items
|
|
574
|
+
*/
|
|
575
|
+
getMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<GameDataItem[]>;
|
|
576
|
+
/**
|
|
577
|
+
* Delete persistent game data
|
|
578
|
+
* @param key Data key
|
|
579
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
580
|
+
* @returns Promise resolving to boolean indicating if data was deleted
|
|
581
|
+
*/
|
|
582
|
+
deleteGameData(key: string, storage?: 'cloud' | 'local'): Promise<boolean>;
|
|
583
|
+
/**
|
|
584
|
+
* Delete multiple persistent game data entries
|
|
585
|
+
* @param keys Array of data keys
|
|
586
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
587
|
+
* @returns Promise resolving to number of entries deleted
|
|
588
|
+
*/
|
|
589
|
+
deleteMultipleGameData(keys: string[], storage?: 'cloud' | 'local'): Promise<number>;
|
|
590
|
+
/**
|
|
591
|
+
* Configure storage mode
|
|
592
|
+
* @param mode Storage mode ('cloud' or 'local')
|
|
593
|
+
*/
|
|
594
|
+
configureStorage(mode: 'cloud' | 'local'): void;
|
|
595
|
+
/**
|
|
596
|
+
* Get current storage mode
|
|
597
|
+
* @returns Current storage mode
|
|
598
|
+
*/
|
|
599
|
+
getStorageMode(): 'cloud' | 'local';
|
|
500
600
|
/**
|
|
501
601
|
* Configure ads service
|
|
502
602
|
* @param config Ads configuration
|
|
@@ -574,6 +674,47 @@ declare class HyveClient {
|
|
|
574
674
|
onBillingLog(callback: (level: "info" | "warn" | "error", message: string, data?: any) => void): void;
|
|
575
675
|
}
|
|
576
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Storage adapter interface - supports cloud and local implementations
|
|
679
|
+
*/
|
|
680
|
+
interface StorageAdapter {
|
|
681
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
682
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
683
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
684
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
685
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
686
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Cloud storage adapter - stores data via API calls to backend
|
|
690
|
+
*/
|
|
691
|
+
declare class CloudStorageAdapter implements StorageAdapter {
|
|
692
|
+
private callApi;
|
|
693
|
+
constructor(callApi: <T = any>(endpoint: string, options?: RequestInit) => Promise<T>);
|
|
694
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
695
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
696
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
697
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
698
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
699
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Local storage adapter - stores data in browser's localStorage
|
|
703
|
+
* Namespaced by game_id only (device-specific storage)
|
|
704
|
+
*/
|
|
705
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
706
|
+
private getUserId;
|
|
707
|
+
private readonly storagePrefix;
|
|
708
|
+
constructor(getUserId: () => string | null);
|
|
709
|
+
private getStorageKey;
|
|
710
|
+
saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
|
|
711
|
+
batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
|
|
712
|
+
getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
|
|
713
|
+
getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
|
|
714
|
+
deleteGameData(gameId: string, key: string): Promise<boolean>;
|
|
715
|
+
deleteMultipleGameData(gameId: string, keys: string[]): Promise<number>;
|
|
716
|
+
}
|
|
717
|
+
|
|
577
718
|
/**
|
|
578
719
|
* Logger utility for the Hyve SDK
|
|
579
720
|
* Automatically enabled in development (NODE_ENV !== 'production')
|
|
@@ -847,4 +988,4 @@ declare class NativeBridge {
|
|
|
847
988
|
*/
|
|
848
989
|
declare function generateUUID(): string;
|
|
849
990
|
|
|
850
|
-
export { type AdConfig$1 as AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, type PurchaseResult, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, logger, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };
|
|
991
|
+
export { type AdConfig$1 as AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, logger, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,9 @@ __export(index_exports, {
|
|
|
23
23
|
AdsService: () => AdsService,
|
|
24
24
|
BillingPlatform: () => BillingPlatform,
|
|
25
25
|
BillingService: () => BillingService,
|
|
26
|
+
CloudStorageAdapter: () => CloudStorageAdapter,
|
|
26
27
|
HyveClient: () => HyveClient,
|
|
28
|
+
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
27
29
|
Logger: () => Logger,
|
|
28
30
|
NativeBridge: () => NativeBridge,
|
|
29
31
|
NativeMessageType: () => NativeMessageType,
|
|
@@ -1249,14 +1251,21 @@ var BillingService = class {
|
|
|
1249
1251
|
throw new Error("Stripe not initialized");
|
|
1250
1252
|
}
|
|
1251
1253
|
try {
|
|
1254
|
+
if (this.checkoutElement) {
|
|
1255
|
+
this.log("info", "[BillingService] Unmounting existing checkout element");
|
|
1256
|
+
this.unmountCheckoutElement();
|
|
1257
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1258
|
+
}
|
|
1252
1259
|
const container = document.getElementById(elementId);
|
|
1253
1260
|
if (!container) {
|
|
1254
1261
|
throw new Error(`Element with id "${elementId}" not found in the DOM`);
|
|
1255
1262
|
}
|
|
1256
1263
|
container.innerHTML = "";
|
|
1264
|
+
this.log("info", "[BillingService] Creating new checkout instance");
|
|
1257
1265
|
this.checkoutElement = await this.stripe.initEmbeddedCheckout({
|
|
1258
1266
|
clientSecret
|
|
1259
1267
|
});
|
|
1268
|
+
this.log("info", "[BillingService] Mounting checkout element to DOM");
|
|
1260
1269
|
this.checkoutElement.mount(`#${elementId}`);
|
|
1261
1270
|
this.setupCheckoutEventListeners();
|
|
1262
1271
|
} catch (error) {
|
|
@@ -1294,7 +1303,14 @@ var BillingService = class {
|
|
|
1294
1303
|
*/
|
|
1295
1304
|
unmountCheckoutElement() {
|
|
1296
1305
|
if (this.checkoutElement) {
|
|
1297
|
-
|
|
1306
|
+
try {
|
|
1307
|
+
this.checkoutElement.unmount();
|
|
1308
|
+
if (typeof this.checkoutElement.destroy === "function") {
|
|
1309
|
+
this.checkoutElement.destroy();
|
|
1310
|
+
}
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
this.log("warn", "[BillingService] Error unmounting checkout element:", error?.message);
|
|
1313
|
+
}
|
|
1298
1314
|
this.checkoutElement = null;
|
|
1299
1315
|
}
|
|
1300
1316
|
}
|
|
@@ -1330,6 +1346,133 @@ var BillingService = class {
|
|
|
1330
1346
|
}
|
|
1331
1347
|
};
|
|
1332
1348
|
|
|
1349
|
+
// src/services/storage.ts
|
|
1350
|
+
var CloudStorageAdapter = class {
|
|
1351
|
+
constructor(callApi) {
|
|
1352
|
+
this.callApi = callApi;
|
|
1353
|
+
}
|
|
1354
|
+
async saveGameData(gameId, key, value) {
|
|
1355
|
+
return this.callApi("/api/v1/persistent-game-data", {
|
|
1356
|
+
method: "POST",
|
|
1357
|
+
headers: {
|
|
1358
|
+
"Content-Type": "application/json"
|
|
1359
|
+
},
|
|
1360
|
+
body: JSON.stringify({ game_id: gameId, key, value })
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
async batchSaveGameData(gameId, items) {
|
|
1364
|
+
return this.callApi(
|
|
1365
|
+
"/api/v1/persistent-game-data/batch",
|
|
1366
|
+
{
|
|
1367
|
+
method: "POST",
|
|
1368
|
+
headers: {
|
|
1369
|
+
"Content-Type": "application/json"
|
|
1370
|
+
},
|
|
1371
|
+
body: JSON.stringify({ game_id: gameId, items })
|
|
1372
|
+
}
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
async getGameData(gameId, key) {
|
|
1376
|
+
try {
|
|
1377
|
+
const params = new URLSearchParams({ game_id: gameId, key });
|
|
1378
|
+
const response = await this.callApi(
|
|
1379
|
+
`/api/v1/persistent-game-data?${params}`
|
|
1380
|
+
);
|
|
1381
|
+
return response.data;
|
|
1382
|
+
} catch (error) {
|
|
1383
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
1384
|
+
return null;
|
|
1385
|
+
}
|
|
1386
|
+
throw error;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
async getMultipleGameData(gameId, keys) {
|
|
1390
|
+
const params = new URLSearchParams({ game_id: gameId });
|
|
1391
|
+
keys.forEach((key) => params.append("keys", key));
|
|
1392
|
+
const response = await this.callApi(
|
|
1393
|
+
`/api/v1/persistent-game-data?${params}`
|
|
1394
|
+
);
|
|
1395
|
+
return response.data;
|
|
1396
|
+
}
|
|
1397
|
+
async deleteGameData(gameId, key) {
|
|
1398
|
+
try {
|
|
1399
|
+
const params = new URLSearchParams({ game_id: gameId, key });
|
|
1400
|
+
const response = await this.callApi(
|
|
1401
|
+
`/api/v1/persistent-game-data?${params}`,
|
|
1402
|
+
{ method: "DELETE" }
|
|
1403
|
+
);
|
|
1404
|
+
return response.success && response.deleted_count > 0;
|
|
1405
|
+
} catch (error) {
|
|
1406
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
throw error;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
async deleteMultipleGameData(gameId, keys) {
|
|
1413
|
+
const params = new URLSearchParams({ game_id: gameId });
|
|
1414
|
+
keys.forEach((key) => params.append("keys", key));
|
|
1415
|
+
const response = await this.callApi(
|
|
1416
|
+
`/api/v1/persistent-game-data?${params}`,
|
|
1417
|
+
{ method: "DELETE" }
|
|
1418
|
+
);
|
|
1419
|
+
return response.deleted_count;
|
|
1420
|
+
}
|
|
1421
|
+
};
|
|
1422
|
+
var LocalStorageAdapter = class {
|
|
1423
|
+
constructor(getUserId) {
|
|
1424
|
+
this.getUserId = getUserId;
|
|
1425
|
+
}
|
|
1426
|
+
storagePrefix = "hyve_game_data";
|
|
1427
|
+
getStorageKey(gameId, key) {
|
|
1428
|
+
return `${this.storagePrefix}:${gameId}:${key}`;
|
|
1429
|
+
}
|
|
1430
|
+
async saveGameData(gameId, key, value) {
|
|
1431
|
+
try {
|
|
1432
|
+
const storageKey = this.getStorageKey(gameId, key);
|
|
1433
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1434
|
+
const existing = localStorage.getItem(storageKey);
|
|
1435
|
+
const createdAt = existing ? JSON.parse(existing).created_at || now : now;
|
|
1436
|
+
const item = { key, value, created_at: createdAt, updated_at: now };
|
|
1437
|
+
localStorage.setItem(storageKey, JSON.stringify(item));
|
|
1438
|
+
return { success: true, message: "Data saved successfully" };
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
throw new Error(`Failed to save: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
async batchSaveGameData(gameId, items) {
|
|
1444
|
+
for (const item of items) {
|
|
1445
|
+
await this.saveGameData(gameId, item.key, item.value);
|
|
1446
|
+
}
|
|
1447
|
+
return { success: true, message: `${items.length} items saved` };
|
|
1448
|
+
}
|
|
1449
|
+
async getGameData(gameId, key) {
|
|
1450
|
+
const data = localStorage.getItem(this.getStorageKey(gameId, key));
|
|
1451
|
+
return data ? JSON.parse(data) : null;
|
|
1452
|
+
}
|
|
1453
|
+
async getMultipleGameData(gameId, keys) {
|
|
1454
|
+
const items = [];
|
|
1455
|
+
for (const key of keys) {
|
|
1456
|
+
const item = await this.getGameData(gameId, key);
|
|
1457
|
+
if (item) items.push(item);
|
|
1458
|
+
}
|
|
1459
|
+
return items;
|
|
1460
|
+
}
|
|
1461
|
+
async deleteGameData(gameId, key) {
|
|
1462
|
+
const storageKey = this.getStorageKey(gameId, key);
|
|
1463
|
+
const exists = localStorage.getItem(storageKey) !== null;
|
|
1464
|
+
if (exists) localStorage.removeItem(storageKey);
|
|
1465
|
+
return exists;
|
|
1466
|
+
}
|
|
1467
|
+
async deleteMultipleGameData(gameId, keys) {
|
|
1468
|
+
let count = 0;
|
|
1469
|
+
for (const key of keys) {
|
|
1470
|
+
if (await this.deleteGameData(gameId, key)) count++;
|
|
1471
|
+
}
|
|
1472
|
+
return count;
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1333
1476
|
// src/core/client.ts
|
|
1334
1477
|
function determineEnvironmentFromParentUrl() {
|
|
1335
1478
|
try {
|
|
@@ -1371,6 +1514,9 @@ var HyveClient = class {
|
|
|
1371
1514
|
billingConfig;
|
|
1372
1515
|
// Store callbacks to preserve them when recreating BillingService
|
|
1373
1516
|
billingCallbacks = {};
|
|
1517
|
+
storageMode;
|
|
1518
|
+
cloudStorageAdapter;
|
|
1519
|
+
localStorageAdapter;
|
|
1374
1520
|
/**
|
|
1375
1521
|
* Creates a new HyveClient instance
|
|
1376
1522
|
* @param config Optional configuration including telemetry and ads
|
|
@@ -1393,6 +1539,11 @@ var HyveClient = class {
|
|
|
1393
1539
|
}
|
|
1394
1540
|
this.billingConfig = config?.billing || {};
|
|
1395
1541
|
this.billingService = new BillingService(this.billingConfig);
|
|
1542
|
+
this.storageMode = config?.storageMode || "cloud";
|
|
1543
|
+
this.cloudStorageAdapter = new CloudStorageAdapter(
|
|
1544
|
+
(endpoint, options) => this.callApi(endpoint, options)
|
|
1545
|
+
);
|
|
1546
|
+
this.localStorageAdapter = new LocalStorageAdapter(() => this.getUserId());
|
|
1396
1547
|
const envSource = config?.isDev !== void 0 ? "explicit config" : "auto-detected from parent URL";
|
|
1397
1548
|
logger.info("==========================================");
|
|
1398
1549
|
logger.info("HyveClient Initialized");
|
|
@@ -1409,11 +1560,13 @@ var HyveClient = class {
|
|
|
1409
1560
|
"Billing configured:",
|
|
1410
1561
|
Object.keys(this.billingConfig).length > 0
|
|
1411
1562
|
);
|
|
1563
|
+
logger.info("Storage mode:", this.storageMode);
|
|
1412
1564
|
logger.debug("Config:", {
|
|
1413
1565
|
isDev: this.telemetryConfig.isDev,
|
|
1414
1566
|
hasCustomApiUrl: !!config?.apiBaseUrl,
|
|
1415
1567
|
adsEnabled: config?.ads?.enabled || false,
|
|
1416
|
-
billingConfigured: Object.keys(this.billingConfig).length > 0
|
|
1568
|
+
billingConfigured: Object.keys(this.billingConfig).length > 0,
|
|
1569
|
+
storageMode: this.storageMode
|
|
1417
1570
|
});
|
|
1418
1571
|
logger.info("==========================================");
|
|
1419
1572
|
}
|
|
@@ -1678,6 +1831,146 @@ var HyveClient = class {
|
|
|
1678
1831
|
this.sessionId = generateUUID();
|
|
1679
1832
|
logger.info("Client reset with new sessionId:", this.sessionId);
|
|
1680
1833
|
}
|
|
1834
|
+
/**
|
|
1835
|
+
* Get the storage adapter based on mode
|
|
1836
|
+
* @param mode Storage mode override (cloud or local)
|
|
1837
|
+
*/
|
|
1838
|
+
getStorageAdapter(mode) {
|
|
1839
|
+
const storageMode = mode || this.storageMode;
|
|
1840
|
+
return storageMode === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Save persistent game data
|
|
1844
|
+
* @param key Data key
|
|
1845
|
+
* @param value Data value (any JSON-serializable value)
|
|
1846
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1847
|
+
* @returns Promise resolving to save response
|
|
1848
|
+
*/
|
|
1849
|
+
async saveGameData(key, value, storage) {
|
|
1850
|
+
const gameId = this.getGameId();
|
|
1851
|
+
if (!gameId) {
|
|
1852
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1853
|
+
}
|
|
1854
|
+
const storageMode = storage || this.storageMode;
|
|
1855
|
+
logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
|
|
1856
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1857
|
+
const response = await adapter.saveGameData(gameId, key, value);
|
|
1858
|
+
logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
|
|
1859
|
+
return response;
|
|
1860
|
+
}
|
|
1861
|
+
/**
|
|
1862
|
+
* Batch save persistent game data
|
|
1863
|
+
* @param items Array of key-value pairs to save
|
|
1864
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1865
|
+
* @returns Promise resolving to save response
|
|
1866
|
+
*/
|
|
1867
|
+
async batchSaveGameData(items, storage) {
|
|
1868
|
+
const gameId = this.getGameId();
|
|
1869
|
+
if (!gameId) {
|
|
1870
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1871
|
+
}
|
|
1872
|
+
const storageMode = storage || this.storageMode;
|
|
1873
|
+
logger.debug(`Batch saving ${items.length} game data entries to ${storageMode} for game: ${gameId}`);
|
|
1874
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1875
|
+
const response = await adapter.batchSaveGameData(gameId, items);
|
|
1876
|
+
logger.info(`Batch saved ${items.length} game data entries successfully to ${storageMode}`);
|
|
1877
|
+
return response;
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Get persistent game data
|
|
1881
|
+
* @param key Data key
|
|
1882
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1883
|
+
* @returns Promise resolving to game data item or null if not found
|
|
1884
|
+
*/
|
|
1885
|
+
async getGameData(key, storage) {
|
|
1886
|
+
const gameId = this.getGameId();
|
|
1887
|
+
if (!gameId) {
|
|
1888
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1889
|
+
}
|
|
1890
|
+
const storageMode = storage || this.storageMode;
|
|
1891
|
+
logger.debug(`Getting game data from ${storageMode}: ${gameId}/${key}`);
|
|
1892
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1893
|
+
const data = await adapter.getGameData(gameId, key);
|
|
1894
|
+
if (data) {
|
|
1895
|
+
logger.info(`Game data retrieved successfully from ${storageMode}: ${gameId}/${key}`);
|
|
1896
|
+
} else {
|
|
1897
|
+
logger.debug(`Game data not found in ${storageMode}: ${key}`);
|
|
1898
|
+
}
|
|
1899
|
+
return data;
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Get multiple persistent game data entries
|
|
1903
|
+
* @param keys Array of data keys
|
|
1904
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1905
|
+
* @returns Promise resolving to array of game data items
|
|
1906
|
+
*/
|
|
1907
|
+
async getMultipleGameData(keys, storage) {
|
|
1908
|
+
const gameId = this.getGameId();
|
|
1909
|
+
if (!gameId) {
|
|
1910
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1911
|
+
}
|
|
1912
|
+
const storageMode = storage || this.storageMode;
|
|
1913
|
+
logger.debug(`Getting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
|
|
1914
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1915
|
+
const data = await adapter.getMultipleGameData(gameId, keys);
|
|
1916
|
+
logger.info(`Retrieved ${data.length} game data entries from ${storageMode}`);
|
|
1917
|
+
return data;
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Delete persistent game data
|
|
1921
|
+
* @param key Data key
|
|
1922
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1923
|
+
* @returns Promise resolving to boolean indicating if data was deleted
|
|
1924
|
+
*/
|
|
1925
|
+
async deleteGameData(key, storage) {
|
|
1926
|
+
const gameId = this.getGameId();
|
|
1927
|
+
if (!gameId) {
|
|
1928
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1929
|
+
}
|
|
1930
|
+
const storageMode = storage || this.storageMode;
|
|
1931
|
+
logger.debug(`Deleting game data from ${storageMode}: ${gameId}/${key}`);
|
|
1932
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1933
|
+
const deleted = await adapter.deleteGameData(gameId, key);
|
|
1934
|
+
if (deleted) {
|
|
1935
|
+
logger.info(`Game data deleted successfully from ${storageMode}: ${gameId}/${key}`);
|
|
1936
|
+
} else {
|
|
1937
|
+
logger.debug(`Game data not found in ${storageMode}: ${key}`);
|
|
1938
|
+
}
|
|
1939
|
+
return deleted;
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Delete multiple persistent game data entries
|
|
1943
|
+
* @param keys Array of data keys
|
|
1944
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1945
|
+
* @returns Promise resolving to number of entries deleted
|
|
1946
|
+
*/
|
|
1947
|
+
async deleteMultipleGameData(keys, storage) {
|
|
1948
|
+
const gameId = this.getGameId();
|
|
1949
|
+
if (!gameId) {
|
|
1950
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1951
|
+
}
|
|
1952
|
+
const storageMode = storage || this.storageMode;
|
|
1953
|
+
logger.debug(`Deleting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
|
|
1954
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1955
|
+
const deletedCount = await adapter.deleteMultipleGameData(gameId, keys);
|
|
1956
|
+
logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
|
|
1957
|
+
return deletedCount;
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Configure storage mode
|
|
1961
|
+
* @param mode Storage mode ('cloud' or 'local')
|
|
1962
|
+
*/
|
|
1963
|
+
configureStorage(mode) {
|
|
1964
|
+
this.storageMode = mode;
|
|
1965
|
+
logger.info("Storage mode updated to:", mode);
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Get current storage mode
|
|
1969
|
+
* @returns Current storage mode
|
|
1970
|
+
*/
|
|
1971
|
+
getStorageMode() {
|
|
1972
|
+
return this.storageMode;
|
|
1973
|
+
}
|
|
1681
1974
|
/**
|
|
1682
1975
|
* Configure ads service
|
|
1683
1976
|
* @param config Ads configuration
|
|
@@ -1815,7 +2108,9 @@ var HyveClient = class {
|
|
|
1815
2108
|
AdsService,
|
|
1816
2109
|
BillingPlatform,
|
|
1817
2110
|
BillingService,
|
|
2111
|
+
CloudStorageAdapter,
|
|
1818
2112
|
HyveClient,
|
|
2113
|
+
LocalStorageAdapter,
|
|
1819
2114
|
Logger,
|
|
1820
2115
|
NativeBridge,
|
|
1821
2116
|
NativeMessageType,
|
package/dist/index.mjs
CHANGED
|
@@ -1209,14 +1209,21 @@ var BillingService = class {
|
|
|
1209
1209
|
throw new Error("Stripe not initialized");
|
|
1210
1210
|
}
|
|
1211
1211
|
try {
|
|
1212
|
+
if (this.checkoutElement) {
|
|
1213
|
+
this.log("info", "[BillingService] Unmounting existing checkout element");
|
|
1214
|
+
this.unmountCheckoutElement();
|
|
1215
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1216
|
+
}
|
|
1212
1217
|
const container = document.getElementById(elementId);
|
|
1213
1218
|
if (!container) {
|
|
1214
1219
|
throw new Error(`Element with id "${elementId}" not found in the DOM`);
|
|
1215
1220
|
}
|
|
1216
1221
|
container.innerHTML = "";
|
|
1222
|
+
this.log("info", "[BillingService] Creating new checkout instance");
|
|
1217
1223
|
this.checkoutElement = await this.stripe.initEmbeddedCheckout({
|
|
1218
1224
|
clientSecret
|
|
1219
1225
|
});
|
|
1226
|
+
this.log("info", "[BillingService] Mounting checkout element to DOM");
|
|
1220
1227
|
this.checkoutElement.mount(`#${elementId}`);
|
|
1221
1228
|
this.setupCheckoutEventListeners();
|
|
1222
1229
|
} catch (error) {
|
|
@@ -1254,7 +1261,14 @@ var BillingService = class {
|
|
|
1254
1261
|
*/
|
|
1255
1262
|
unmountCheckoutElement() {
|
|
1256
1263
|
if (this.checkoutElement) {
|
|
1257
|
-
|
|
1264
|
+
try {
|
|
1265
|
+
this.checkoutElement.unmount();
|
|
1266
|
+
if (typeof this.checkoutElement.destroy === "function") {
|
|
1267
|
+
this.checkoutElement.destroy();
|
|
1268
|
+
}
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
this.log("warn", "[BillingService] Error unmounting checkout element:", error?.message);
|
|
1271
|
+
}
|
|
1258
1272
|
this.checkoutElement = null;
|
|
1259
1273
|
}
|
|
1260
1274
|
}
|
|
@@ -1290,6 +1304,133 @@ var BillingService = class {
|
|
|
1290
1304
|
}
|
|
1291
1305
|
};
|
|
1292
1306
|
|
|
1307
|
+
// src/services/storage.ts
|
|
1308
|
+
var CloudStorageAdapter = class {
|
|
1309
|
+
constructor(callApi) {
|
|
1310
|
+
this.callApi = callApi;
|
|
1311
|
+
}
|
|
1312
|
+
async saveGameData(gameId, key, value) {
|
|
1313
|
+
return this.callApi("/api/v1/persistent-game-data", {
|
|
1314
|
+
method: "POST",
|
|
1315
|
+
headers: {
|
|
1316
|
+
"Content-Type": "application/json"
|
|
1317
|
+
},
|
|
1318
|
+
body: JSON.stringify({ game_id: gameId, key, value })
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
async batchSaveGameData(gameId, items) {
|
|
1322
|
+
return this.callApi(
|
|
1323
|
+
"/api/v1/persistent-game-data/batch",
|
|
1324
|
+
{
|
|
1325
|
+
method: "POST",
|
|
1326
|
+
headers: {
|
|
1327
|
+
"Content-Type": "application/json"
|
|
1328
|
+
},
|
|
1329
|
+
body: JSON.stringify({ game_id: gameId, items })
|
|
1330
|
+
}
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
async getGameData(gameId, key) {
|
|
1334
|
+
try {
|
|
1335
|
+
const params = new URLSearchParams({ game_id: gameId, key });
|
|
1336
|
+
const response = await this.callApi(
|
|
1337
|
+
`/api/v1/persistent-game-data?${params}`
|
|
1338
|
+
);
|
|
1339
|
+
return response.data;
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
1342
|
+
return null;
|
|
1343
|
+
}
|
|
1344
|
+
throw error;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
async getMultipleGameData(gameId, keys) {
|
|
1348
|
+
const params = new URLSearchParams({ game_id: gameId });
|
|
1349
|
+
keys.forEach((key) => params.append("keys", key));
|
|
1350
|
+
const response = await this.callApi(
|
|
1351
|
+
`/api/v1/persistent-game-data?${params}`
|
|
1352
|
+
);
|
|
1353
|
+
return response.data;
|
|
1354
|
+
}
|
|
1355
|
+
async deleteGameData(gameId, key) {
|
|
1356
|
+
try {
|
|
1357
|
+
const params = new URLSearchParams({ game_id: gameId, key });
|
|
1358
|
+
const response = await this.callApi(
|
|
1359
|
+
`/api/v1/persistent-game-data?${params}`,
|
|
1360
|
+
{ method: "DELETE" }
|
|
1361
|
+
);
|
|
1362
|
+
return response.success && response.deleted_count > 0;
|
|
1363
|
+
} catch (error) {
|
|
1364
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
1365
|
+
return false;
|
|
1366
|
+
}
|
|
1367
|
+
throw error;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
async deleteMultipleGameData(gameId, keys) {
|
|
1371
|
+
const params = new URLSearchParams({ game_id: gameId });
|
|
1372
|
+
keys.forEach((key) => params.append("keys", key));
|
|
1373
|
+
const response = await this.callApi(
|
|
1374
|
+
`/api/v1/persistent-game-data?${params}`,
|
|
1375
|
+
{ method: "DELETE" }
|
|
1376
|
+
);
|
|
1377
|
+
return response.deleted_count;
|
|
1378
|
+
}
|
|
1379
|
+
};
|
|
1380
|
+
var LocalStorageAdapter = class {
|
|
1381
|
+
constructor(getUserId) {
|
|
1382
|
+
this.getUserId = getUserId;
|
|
1383
|
+
}
|
|
1384
|
+
storagePrefix = "hyve_game_data";
|
|
1385
|
+
getStorageKey(gameId, key) {
|
|
1386
|
+
return `${this.storagePrefix}:${gameId}:${key}`;
|
|
1387
|
+
}
|
|
1388
|
+
async saveGameData(gameId, key, value) {
|
|
1389
|
+
try {
|
|
1390
|
+
const storageKey = this.getStorageKey(gameId, key);
|
|
1391
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1392
|
+
const existing = localStorage.getItem(storageKey);
|
|
1393
|
+
const createdAt = existing ? JSON.parse(existing).created_at || now : now;
|
|
1394
|
+
const item = { key, value, created_at: createdAt, updated_at: now };
|
|
1395
|
+
localStorage.setItem(storageKey, JSON.stringify(item));
|
|
1396
|
+
return { success: true, message: "Data saved successfully" };
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
throw new Error(`Failed to save: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
async batchSaveGameData(gameId, items) {
|
|
1402
|
+
for (const item of items) {
|
|
1403
|
+
await this.saveGameData(gameId, item.key, item.value);
|
|
1404
|
+
}
|
|
1405
|
+
return { success: true, message: `${items.length} items saved` };
|
|
1406
|
+
}
|
|
1407
|
+
async getGameData(gameId, key) {
|
|
1408
|
+
const data = localStorage.getItem(this.getStorageKey(gameId, key));
|
|
1409
|
+
return data ? JSON.parse(data) : null;
|
|
1410
|
+
}
|
|
1411
|
+
async getMultipleGameData(gameId, keys) {
|
|
1412
|
+
const items = [];
|
|
1413
|
+
for (const key of keys) {
|
|
1414
|
+
const item = await this.getGameData(gameId, key);
|
|
1415
|
+
if (item) items.push(item);
|
|
1416
|
+
}
|
|
1417
|
+
return items;
|
|
1418
|
+
}
|
|
1419
|
+
async deleteGameData(gameId, key) {
|
|
1420
|
+
const storageKey = this.getStorageKey(gameId, key);
|
|
1421
|
+
const exists = localStorage.getItem(storageKey) !== null;
|
|
1422
|
+
if (exists) localStorage.removeItem(storageKey);
|
|
1423
|
+
return exists;
|
|
1424
|
+
}
|
|
1425
|
+
async deleteMultipleGameData(gameId, keys) {
|
|
1426
|
+
let count = 0;
|
|
1427
|
+
for (const key of keys) {
|
|
1428
|
+
if (await this.deleteGameData(gameId, key)) count++;
|
|
1429
|
+
}
|
|
1430
|
+
return count;
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1293
1434
|
// src/core/client.ts
|
|
1294
1435
|
function determineEnvironmentFromParentUrl() {
|
|
1295
1436
|
try {
|
|
@@ -1331,6 +1472,9 @@ var HyveClient = class {
|
|
|
1331
1472
|
billingConfig;
|
|
1332
1473
|
// Store callbacks to preserve them when recreating BillingService
|
|
1333
1474
|
billingCallbacks = {};
|
|
1475
|
+
storageMode;
|
|
1476
|
+
cloudStorageAdapter;
|
|
1477
|
+
localStorageAdapter;
|
|
1334
1478
|
/**
|
|
1335
1479
|
* Creates a new HyveClient instance
|
|
1336
1480
|
* @param config Optional configuration including telemetry and ads
|
|
@@ -1353,6 +1497,11 @@ var HyveClient = class {
|
|
|
1353
1497
|
}
|
|
1354
1498
|
this.billingConfig = config?.billing || {};
|
|
1355
1499
|
this.billingService = new BillingService(this.billingConfig);
|
|
1500
|
+
this.storageMode = config?.storageMode || "cloud";
|
|
1501
|
+
this.cloudStorageAdapter = new CloudStorageAdapter(
|
|
1502
|
+
(endpoint, options) => this.callApi(endpoint, options)
|
|
1503
|
+
);
|
|
1504
|
+
this.localStorageAdapter = new LocalStorageAdapter(() => this.getUserId());
|
|
1356
1505
|
const envSource = config?.isDev !== void 0 ? "explicit config" : "auto-detected from parent URL";
|
|
1357
1506
|
logger.info("==========================================");
|
|
1358
1507
|
logger.info("HyveClient Initialized");
|
|
@@ -1369,11 +1518,13 @@ var HyveClient = class {
|
|
|
1369
1518
|
"Billing configured:",
|
|
1370
1519
|
Object.keys(this.billingConfig).length > 0
|
|
1371
1520
|
);
|
|
1521
|
+
logger.info("Storage mode:", this.storageMode);
|
|
1372
1522
|
logger.debug("Config:", {
|
|
1373
1523
|
isDev: this.telemetryConfig.isDev,
|
|
1374
1524
|
hasCustomApiUrl: !!config?.apiBaseUrl,
|
|
1375
1525
|
adsEnabled: config?.ads?.enabled || false,
|
|
1376
|
-
billingConfigured: Object.keys(this.billingConfig).length > 0
|
|
1526
|
+
billingConfigured: Object.keys(this.billingConfig).length > 0,
|
|
1527
|
+
storageMode: this.storageMode
|
|
1377
1528
|
});
|
|
1378
1529
|
logger.info("==========================================");
|
|
1379
1530
|
}
|
|
@@ -1638,6 +1789,146 @@ var HyveClient = class {
|
|
|
1638
1789
|
this.sessionId = generateUUID();
|
|
1639
1790
|
logger.info("Client reset with new sessionId:", this.sessionId);
|
|
1640
1791
|
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Get the storage adapter based on mode
|
|
1794
|
+
* @param mode Storage mode override (cloud or local)
|
|
1795
|
+
*/
|
|
1796
|
+
getStorageAdapter(mode) {
|
|
1797
|
+
const storageMode = mode || this.storageMode;
|
|
1798
|
+
return storageMode === "local" ? this.localStorageAdapter : this.cloudStorageAdapter;
|
|
1799
|
+
}
|
|
1800
|
+
/**
|
|
1801
|
+
* Save persistent game data
|
|
1802
|
+
* @param key Data key
|
|
1803
|
+
* @param value Data value (any JSON-serializable value)
|
|
1804
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1805
|
+
* @returns Promise resolving to save response
|
|
1806
|
+
*/
|
|
1807
|
+
async saveGameData(key, value, storage) {
|
|
1808
|
+
const gameId = this.getGameId();
|
|
1809
|
+
if (!gameId) {
|
|
1810
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1811
|
+
}
|
|
1812
|
+
const storageMode = storage || this.storageMode;
|
|
1813
|
+
logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
|
|
1814
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1815
|
+
const response = await adapter.saveGameData(gameId, key, value);
|
|
1816
|
+
logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
|
|
1817
|
+
return response;
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* Batch save persistent game data
|
|
1821
|
+
* @param items Array of key-value pairs to save
|
|
1822
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1823
|
+
* @returns Promise resolving to save response
|
|
1824
|
+
*/
|
|
1825
|
+
async batchSaveGameData(items, storage) {
|
|
1826
|
+
const gameId = this.getGameId();
|
|
1827
|
+
if (!gameId) {
|
|
1828
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1829
|
+
}
|
|
1830
|
+
const storageMode = storage || this.storageMode;
|
|
1831
|
+
logger.debug(`Batch saving ${items.length} game data entries to ${storageMode} for game: ${gameId}`);
|
|
1832
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1833
|
+
const response = await adapter.batchSaveGameData(gameId, items);
|
|
1834
|
+
logger.info(`Batch saved ${items.length} game data entries successfully to ${storageMode}`);
|
|
1835
|
+
return response;
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Get persistent game data
|
|
1839
|
+
* @param key Data key
|
|
1840
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1841
|
+
* @returns Promise resolving to game data item or null if not found
|
|
1842
|
+
*/
|
|
1843
|
+
async getGameData(key, storage) {
|
|
1844
|
+
const gameId = this.getGameId();
|
|
1845
|
+
if (!gameId) {
|
|
1846
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1847
|
+
}
|
|
1848
|
+
const storageMode = storage || this.storageMode;
|
|
1849
|
+
logger.debug(`Getting game data from ${storageMode}: ${gameId}/${key}`);
|
|
1850
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1851
|
+
const data = await adapter.getGameData(gameId, key);
|
|
1852
|
+
if (data) {
|
|
1853
|
+
logger.info(`Game data retrieved successfully from ${storageMode}: ${gameId}/${key}`);
|
|
1854
|
+
} else {
|
|
1855
|
+
logger.debug(`Game data not found in ${storageMode}: ${key}`);
|
|
1856
|
+
}
|
|
1857
|
+
return data;
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Get multiple persistent game data entries
|
|
1861
|
+
* @param keys Array of data keys
|
|
1862
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1863
|
+
* @returns Promise resolving to array of game data items
|
|
1864
|
+
*/
|
|
1865
|
+
async getMultipleGameData(keys, storage) {
|
|
1866
|
+
const gameId = this.getGameId();
|
|
1867
|
+
if (!gameId) {
|
|
1868
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1869
|
+
}
|
|
1870
|
+
const storageMode = storage || this.storageMode;
|
|
1871
|
+
logger.debug(`Getting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
|
|
1872
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1873
|
+
const data = await adapter.getMultipleGameData(gameId, keys);
|
|
1874
|
+
logger.info(`Retrieved ${data.length} game data entries from ${storageMode}`);
|
|
1875
|
+
return data;
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* Delete persistent game data
|
|
1879
|
+
* @param key Data key
|
|
1880
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1881
|
+
* @returns Promise resolving to boolean indicating if data was deleted
|
|
1882
|
+
*/
|
|
1883
|
+
async deleteGameData(key, storage) {
|
|
1884
|
+
const gameId = this.getGameId();
|
|
1885
|
+
if (!gameId) {
|
|
1886
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1887
|
+
}
|
|
1888
|
+
const storageMode = storage || this.storageMode;
|
|
1889
|
+
logger.debug(`Deleting game data from ${storageMode}: ${gameId}/${key}`);
|
|
1890
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1891
|
+
const deleted = await adapter.deleteGameData(gameId, key);
|
|
1892
|
+
if (deleted) {
|
|
1893
|
+
logger.info(`Game data deleted successfully from ${storageMode}: ${gameId}/${key}`);
|
|
1894
|
+
} else {
|
|
1895
|
+
logger.debug(`Game data not found in ${storageMode}: ${key}`);
|
|
1896
|
+
}
|
|
1897
|
+
return deleted;
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Delete multiple persistent game data entries
|
|
1901
|
+
* @param keys Array of data keys
|
|
1902
|
+
* @param storage Storage mode override ('cloud' or 'local')
|
|
1903
|
+
* @returns Promise resolving to number of entries deleted
|
|
1904
|
+
*/
|
|
1905
|
+
async deleteMultipleGameData(keys, storage) {
|
|
1906
|
+
const gameId = this.getGameId();
|
|
1907
|
+
if (!gameId) {
|
|
1908
|
+
throw new Error("game-id is required for persistent storage. Call authenticateFromUrl first.");
|
|
1909
|
+
}
|
|
1910
|
+
const storageMode = storage || this.storageMode;
|
|
1911
|
+
logger.debug(`Deleting ${keys.length} game data entries from ${storageMode} for game: ${gameId}`);
|
|
1912
|
+
const adapter = this.getStorageAdapter(storage);
|
|
1913
|
+
const deletedCount = await adapter.deleteMultipleGameData(gameId, keys);
|
|
1914
|
+
logger.info(`Deleted ${deletedCount} game data entries from ${storageMode}`);
|
|
1915
|
+
return deletedCount;
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Configure storage mode
|
|
1919
|
+
* @param mode Storage mode ('cloud' or 'local')
|
|
1920
|
+
*/
|
|
1921
|
+
configureStorage(mode) {
|
|
1922
|
+
this.storageMode = mode;
|
|
1923
|
+
logger.info("Storage mode updated to:", mode);
|
|
1924
|
+
}
|
|
1925
|
+
/**
|
|
1926
|
+
* Get current storage mode
|
|
1927
|
+
* @returns Current storage mode
|
|
1928
|
+
*/
|
|
1929
|
+
getStorageMode() {
|
|
1930
|
+
return this.storageMode;
|
|
1931
|
+
}
|
|
1641
1932
|
/**
|
|
1642
1933
|
* Configure ads service
|
|
1643
1934
|
* @param config Ads configuration
|
|
@@ -1774,7 +2065,9 @@ export {
|
|
|
1774
2065
|
AdsService,
|
|
1775
2066
|
BillingPlatform,
|
|
1776
2067
|
BillingService,
|
|
2068
|
+
CloudStorageAdapter,
|
|
1777
2069
|
HyveClient,
|
|
2070
|
+
LocalStorageAdapter,
|
|
1778
2071
|
Logger,
|
|
1779
2072
|
NativeBridge,
|
|
1780
2073
|
NativeMessageType,
|