@hyve-sdk/js 2.1.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -72,6 +72,8 @@ interface Inventory {
72
72
  type GameDataValue = string | number | boolean | null | GameDataValue[] | {
73
73
  [key: string]: GameDataValue;
74
74
  };
75
+ /** Atomic operation type for persistent game data */
76
+ type GameDataOperation = 'set' | 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'min' | 'max' | 'append';
75
77
  /** Single game data item with metadata */
76
78
  interface GameDataItem {
77
79
  key: string;
@@ -79,10 +81,27 @@ interface GameDataItem {
79
81
  created_at: string;
80
82
  updated_at: string;
81
83
  }
82
- /** Response from save operations */
84
+ /** Response from a single save operation */
83
85
  interface SaveGameDataResponse {
84
86
  success: boolean;
85
87
  message: string;
88
+ /** Resulting value after an atomic operation (only present when operation is used) */
89
+ result?: GameDataValue;
90
+ }
91
+ /** Per-item result in a batch save response */
92
+ interface BatchSaveResultItem {
93
+ key: string;
94
+ success: boolean;
95
+ /** Resulting value after an atomic operation */
96
+ result?: GameDataValue;
97
+ error?: string;
98
+ }
99
+ /** Response from a batch save operation */
100
+ interface BatchSaveGameDataResponse {
101
+ success: boolean;
102
+ message: string;
103
+ /** Per-item results (present when any item uses an operation) */
104
+ results?: BatchSaveResultItem[];
86
105
  }
87
106
  /** Response when getting a single game data entry */
88
107
  interface GetGameDataResponse {
@@ -101,6 +120,10 @@ interface DeleteGameDataResponse {
101
120
  interface GameDataBatchItem {
102
121
  key: string;
103
122
  value: GameDataValue;
123
+ /** Atomic operation to perform on the value */
124
+ operation?: GameDataOperation;
125
+ /** Dot-notation path targeting a nested field (e.g. "stats.score") */
126
+ path?: string;
104
127
  }
105
128
 
106
129
  /**
@@ -522,17 +545,19 @@ declare class HyveClient {
522
545
  * Save persistent game data
523
546
  * @param key Data key
524
547
  * @param value Data value (any JSON-serializable value)
548
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
549
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
525
550
  * @param storage Storage mode override ('cloud' or 'local')
526
551
  * @returns Promise resolving to save response
527
552
  */
528
- saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
553
+ saveGameData(key: string, value: GameDataValue, operation?: GameDataOperation, path?: string, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
529
554
  /**
530
555
  * Batch save persistent game data
531
- * @param items Array of key-value pairs to save
556
+ * @param items Array of items to save (each may include an optional operation and path)
532
557
  * @param storage Storage mode override ('cloud' or 'local')
533
- * @returns Promise resolving to save response
558
+ * @returns Promise resolving to batch save response with per-item results
534
559
  */
535
- batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
560
+ batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<BatchSaveGameDataResponse>;
536
561
  /**
537
562
  * Get persistent game data
538
563
  * @param key Data key
@@ -640,6 +665,12 @@ declare class HyveClient {
640
665
  * Unmount Stripe checkout element
641
666
  */
642
667
  unmountBillingCheckout(): void;
668
+ /**
669
+ * Fetches the rendered HTML view for a project machine
670
+ * @param machineId The machine ID to render
671
+ * @returns Promise resolving to the rendered HTML string
672
+ */
673
+ getMachineRender(machineId: string): Promise<string>;
643
674
  }
644
675
 
645
676
  /**
@@ -794,8 +825,8 @@ declare class CrazyGamesService {
794
825
  * Storage adapter interface - supports cloud and local implementations
795
826
  */
796
827
  interface StorageAdapter {
797
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
798
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
828
+ saveGameData(gameId: string, key: string, value: GameDataValue, operation?: GameDataOperation, path?: string): Promise<SaveGameDataResponse>;
829
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
799
830
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
800
831
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
801
832
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -807,8 +838,8 @@ interface StorageAdapter {
807
838
  declare class CloudStorageAdapter implements StorageAdapter {
808
839
  private callApi;
809
840
  constructor(callApi: <T = any>(endpoint: string, options?: RequestInit) => Promise<T>);
810
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
811
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
841
+ saveGameData(gameId: string, key: string, value: GameDataValue, operation?: GameDataOperation, path?: string): Promise<SaveGameDataResponse>;
842
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
812
843
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
813
844
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
814
845
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -823,8 +854,8 @@ declare class LocalStorageAdapter implements StorageAdapter {
823
854
  private readonly storagePrefix;
824
855
  constructor(getUserId: () => string | null);
825
856
  private getStorageKey;
826
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
827
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
857
+ saveGameData(gameId: string, key: string, value: GameDataValue, _operation?: GameDataOperation, _path?: string): Promise<SaveGameDataResponse>;
858
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
828
859
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
829
860
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
830
861
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -1064,4 +1095,4 @@ declare class NativeBridge {
1064
1095
  */
1065
1096
  declare function generateUUID(): string;
1066
1097
 
1067
- export { type AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, 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, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
1098
+ export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
package/dist/index.d.ts CHANGED
@@ -72,6 +72,8 @@ interface Inventory {
72
72
  type GameDataValue = string | number | boolean | null | GameDataValue[] | {
73
73
  [key: string]: GameDataValue;
74
74
  };
75
+ /** Atomic operation type for persistent game data */
76
+ type GameDataOperation = 'set' | 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'min' | 'max' | 'append';
75
77
  /** Single game data item with metadata */
76
78
  interface GameDataItem {
77
79
  key: string;
@@ -79,10 +81,27 @@ interface GameDataItem {
79
81
  created_at: string;
80
82
  updated_at: string;
81
83
  }
82
- /** Response from save operations */
84
+ /** Response from a single save operation */
83
85
  interface SaveGameDataResponse {
84
86
  success: boolean;
85
87
  message: string;
88
+ /** Resulting value after an atomic operation (only present when operation is used) */
89
+ result?: GameDataValue;
90
+ }
91
+ /** Per-item result in a batch save response */
92
+ interface BatchSaveResultItem {
93
+ key: string;
94
+ success: boolean;
95
+ /** Resulting value after an atomic operation */
96
+ result?: GameDataValue;
97
+ error?: string;
98
+ }
99
+ /** Response from a batch save operation */
100
+ interface BatchSaveGameDataResponse {
101
+ success: boolean;
102
+ message: string;
103
+ /** Per-item results (present when any item uses an operation) */
104
+ results?: BatchSaveResultItem[];
86
105
  }
87
106
  /** Response when getting a single game data entry */
88
107
  interface GetGameDataResponse {
@@ -101,6 +120,10 @@ interface DeleteGameDataResponse {
101
120
  interface GameDataBatchItem {
102
121
  key: string;
103
122
  value: GameDataValue;
123
+ /** Atomic operation to perform on the value */
124
+ operation?: GameDataOperation;
125
+ /** Dot-notation path targeting a nested field (e.g. "stats.score") */
126
+ path?: string;
104
127
  }
105
128
 
106
129
  /**
@@ -522,17 +545,19 @@ declare class HyveClient {
522
545
  * Save persistent game data
523
546
  * @param key Data key
524
547
  * @param value Data value (any JSON-serializable value)
548
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
549
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
525
550
  * @param storage Storage mode override ('cloud' or 'local')
526
551
  * @returns Promise resolving to save response
527
552
  */
528
- saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
553
+ saveGameData(key: string, value: GameDataValue, operation?: GameDataOperation, path?: string, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
529
554
  /**
530
555
  * Batch save persistent game data
531
- * @param items Array of key-value pairs to save
556
+ * @param items Array of items to save (each may include an optional operation and path)
532
557
  * @param storage Storage mode override ('cloud' or 'local')
533
- * @returns Promise resolving to save response
558
+ * @returns Promise resolving to batch save response with per-item results
534
559
  */
535
- batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
560
+ batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<BatchSaveGameDataResponse>;
536
561
  /**
537
562
  * Get persistent game data
538
563
  * @param key Data key
@@ -640,6 +665,12 @@ declare class HyveClient {
640
665
  * Unmount Stripe checkout element
641
666
  */
642
667
  unmountBillingCheckout(): void;
668
+ /**
669
+ * Fetches the rendered HTML view for a project machine
670
+ * @param machineId The machine ID to render
671
+ * @returns Promise resolving to the rendered HTML string
672
+ */
673
+ getMachineRender(machineId: string): Promise<string>;
643
674
  }
644
675
 
645
676
  /**
@@ -794,8 +825,8 @@ declare class CrazyGamesService {
794
825
  * Storage adapter interface - supports cloud and local implementations
795
826
  */
796
827
  interface StorageAdapter {
797
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
798
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
828
+ saveGameData(gameId: string, key: string, value: GameDataValue, operation?: GameDataOperation, path?: string): Promise<SaveGameDataResponse>;
829
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
799
830
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
800
831
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
801
832
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -807,8 +838,8 @@ interface StorageAdapter {
807
838
  declare class CloudStorageAdapter implements StorageAdapter {
808
839
  private callApi;
809
840
  constructor(callApi: <T = any>(endpoint: string, options?: RequestInit) => Promise<T>);
810
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
811
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
841
+ saveGameData(gameId: string, key: string, value: GameDataValue, operation?: GameDataOperation, path?: string): Promise<SaveGameDataResponse>;
842
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
812
843
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
813
844
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
814
845
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -823,8 +854,8 @@ declare class LocalStorageAdapter implements StorageAdapter {
823
854
  private readonly storagePrefix;
824
855
  constructor(getUserId: () => string | null);
825
856
  private getStorageKey;
826
- saveGameData(gameId: string, key: string, value: GameDataValue): Promise<SaveGameDataResponse>;
827
- batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<SaveGameDataResponse>;
857
+ saveGameData(gameId: string, key: string, value: GameDataValue, _operation?: GameDataOperation, _path?: string): Promise<SaveGameDataResponse>;
858
+ batchSaveGameData(gameId: string, items: GameDataBatchItem[]): Promise<BatchSaveGameDataResponse>;
828
859
  getGameData(gameId: string, key: string): Promise<GameDataItem | null>;
829
860
  getMultipleGameData(gameId: string, keys: string[]): Promise<GameDataItem[]>;
830
861
  deleteGameData(gameId: string, key: string): Promise<boolean>;
@@ -1064,4 +1095,4 @@ declare class NativeBridge {
1064
1095
  */
1065
1096
  declare function generateUUID(): string;
1066
1097
 
1067
- export { type AdConfig, type AdResult, type AdType, AdsService, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, 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, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
1098
+ export { type AdConfig, type AdResult, type AdType, AdsService, type BatchSaveGameDataResponse, type BatchSaveResultItem, type BillingConfig, BillingPlatform, type BillingProduct, BillingService, CloudStorageAdapter, CrazyGamesService, type DeleteGameDataResponse, type GameDataBatchItem, type GameDataItem, type GameDataOperation, type GameDataValue, type GetGameDataBatchResponse, type GetGameDataResponse, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, LocalStorageAdapter, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, PlaygamaService, type PurchaseResult, type SaveGameDataResponse, type StorageAdapter, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, isDomainAllowed, logger, parseUrlParams };
package/dist/index.js CHANGED
@@ -1433,13 +1433,19 @@ var CloudStorageAdapter = class {
1433
1433
  constructor(callApi) {
1434
1434
  this.callApi = callApi;
1435
1435
  }
1436
- async saveGameData(gameId, key, value) {
1436
+ async saveGameData(gameId, key, value, operation, path) {
1437
1437
  return this.callApi("/api/v1/persistent-game-data", {
1438
1438
  method: "POST",
1439
1439
  headers: {
1440
1440
  "Content-Type": "application/json"
1441
1441
  },
1442
- body: JSON.stringify({ game_id: gameId, key, value })
1442
+ body: JSON.stringify({
1443
+ game_id: gameId,
1444
+ key,
1445
+ value,
1446
+ ...operation !== void 0 && { operation },
1447
+ ...path !== void 0 && { path }
1448
+ })
1443
1449
  });
1444
1450
  }
1445
1451
  async batchSaveGameData(gameId, items) {
@@ -1509,7 +1515,7 @@ var LocalStorageAdapter = class {
1509
1515
  getStorageKey(gameId, key) {
1510
1516
  return `${this.storagePrefix}:${gameId}:${key}`;
1511
1517
  }
1512
- async saveGameData(gameId, key, value) {
1518
+ async saveGameData(gameId, key, value, _operation, _path) {
1513
1519
  try {
1514
1520
  const storageKey = this.getStorageKey(gameId, key);
1515
1521
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -1941,23 +1947,25 @@ var HyveClient = class {
1941
1947
  * Save persistent game data
1942
1948
  * @param key Data key
1943
1949
  * @param value Data value (any JSON-serializable value)
1950
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
1951
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
1944
1952
  * @param storage Storage mode override ('cloud' or 'local')
1945
1953
  * @returns Promise resolving to save response
1946
1954
  */
1947
- async saveGameData(key, value, storage) {
1955
+ async saveGameData(key, value, operation, path, storage) {
1948
1956
  const gameId = this.requireGameId();
1949
1957
  const storageMode = storage || this.storageMode;
1950
1958
  logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
1951
1959
  const adapter = this.getStorageAdapter(storage);
1952
- const response = await adapter.saveGameData(gameId, key, value);
1960
+ const response = await adapter.saveGameData(gameId, key, value, operation, path);
1953
1961
  logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
1954
1962
  return response;
1955
1963
  }
1956
1964
  /**
1957
1965
  * Batch save persistent game data
1958
- * @param items Array of key-value pairs to save
1966
+ * @param items Array of items to save (each may include an optional operation and path)
1959
1967
  * @param storage Storage mode override ('cloud' or 'local')
1960
- * @returns Promise resolving to save response
1968
+ * @returns Promise resolving to batch save response with per-item results
1961
1969
  */
1962
1970
  async batchSaveGameData(items, storage) {
1963
1971
  const gameId = this.requireGameId();
@@ -2192,6 +2200,33 @@ var HyveClient = class {
2192
2200
  unmountBillingCheckout() {
2193
2201
  this.billingService.unmountCheckoutElement();
2194
2202
  }
2203
+ /**
2204
+ * Fetches the rendered HTML view for a project machine
2205
+ * @param machineId The machine ID to render
2206
+ * @returns Promise resolving to the rendered HTML string
2207
+ */
2208
+ async getMachineRender(machineId) {
2209
+ if (!this.jwtToken) {
2210
+ throw new Error(
2211
+ "No JWT token available. Ensure hyve-access and game-id are present in the URL."
2212
+ );
2213
+ }
2214
+ const gameId = this.requireGameId();
2215
+ logger.debug(`Fetching machine render for machine: ${machineId}`);
2216
+ const url = `${this.apiBaseUrl}/api/v1/project/machines/${machineId}/render?game_id=${gameId}`;
2217
+ const response = await fetch(url, {
2218
+ headers: {
2219
+ Authorization: `Bearer ${this.jwtToken}`
2220
+ }
2221
+ });
2222
+ if (!response.ok) {
2223
+ const errorText = await response.text();
2224
+ throw new Error(`Machine render request failed: ${response.status} ${errorText}`);
2225
+ }
2226
+ const html = await response.text();
2227
+ logger.info(`Machine render fetched successfully for machine: ${machineId}`);
2228
+ return html;
2229
+ }
2195
2230
  };
2196
2231
  // Annotate the CommonJS export names for ESM import in node:
2197
2232
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1393,13 +1393,19 @@ var CloudStorageAdapter = class {
1393
1393
  constructor(callApi) {
1394
1394
  this.callApi = callApi;
1395
1395
  }
1396
- async saveGameData(gameId, key, value) {
1396
+ async saveGameData(gameId, key, value, operation, path) {
1397
1397
  return this.callApi("/api/v1/persistent-game-data", {
1398
1398
  method: "POST",
1399
1399
  headers: {
1400
1400
  "Content-Type": "application/json"
1401
1401
  },
1402
- body: JSON.stringify({ game_id: gameId, key, value })
1402
+ body: JSON.stringify({
1403
+ game_id: gameId,
1404
+ key,
1405
+ value,
1406
+ ...operation !== void 0 && { operation },
1407
+ ...path !== void 0 && { path }
1408
+ })
1403
1409
  });
1404
1410
  }
1405
1411
  async batchSaveGameData(gameId, items) {
@@ -1469,7 +1475,7 @@ var LocalStorageAdapter = class {
1469
1475
  getStorageKey(gameId, key) {
1470
1476
  return `${this.storagePrefix}:${gameId}:${key}`;
1471
1477
  }
1472
- async saveGameData(gameId, key, value) {
1478
+ async saveGameData(gameId, key, value, _operation, _path) {
1473
1479
  try {
1474
1480
  const storageKey = this.getStorageKey(gameId, key);
1475
1481
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -1901,23 +1907,25 @@ var HyveClient = class {
1901
1907
  * Save persistent game data
1902
1908
  * @param key Data key
1903
1909
  * @param value Data value (any JSON-serializable value)
1910
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
1911
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
1904
1912
  * @param storage Storage mode override ('cloud' or 'local')
1905
1913
  * @returns Promise resolving to save response
1906
1914
  */
1907
- async saveGameData(key, value, storage) {
1915
+ async saveGameData(key, value, operation, path, storage) {
1908
1916
  const gameId = this.requireGameId();
1909
1917
  const storageMode = storage || this.storageMode;
1910
1918
  logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
1911
1919
  const adapter = this.getStorageAdapter(storage);
1912
- const response = await adapter.saveGameData(gameId, key, value);
1920
+ const response = await adapter.saveGameData(gameId, key, value, operation, path);
1913
1921
  logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
1914
1922
  return response;
1915
1923
  }
1916
1924
  /**
1917
1925
  * Batch save persistent game data
1918
- * @param items Array of key-value pairs to save
1926
+ * @param items Array of items to save (each may include an optional operation and path)
1919
1927
  * @param storage Storage mode override ('cloud' or 'local')
1920
- * @returns Promise resolving to save response
1928
+ * @returns Promise resolving to batch save response with per-item results
1921
1929
  */
1922
1930
  async batchSaveGameData(items, storage) {
1923
1931
  const gameId = this.requireGameId();
@@ -2152,6 +2160,33 @@ var HyveClient = class {
2152
2160
  unmountBillingCheckout() {
2153
2161
  this.billingService.unmountCheckoutElement();
2154
2162
  }
2163
+ /**
2164
+ * Fetches the rendered HTML view for a project machine
2165
+ * @param machineId The machine ID to render
2166
+ * @returns Promise resolving to the rendered HTML string
2167
+ */
2168
+ async getMachineRender(machineId) {
2169
+ if (!this.jwtToken) {
2170
+ throw new Error(
2171
+ "No JWT token available. Ensure hyve-access and game-id are present in the URL."
2172
+ );
2173
+ }
2174
+ const gameId = this.requireGameId();
2175
+ logger.debug(`Fetching machine render for machine: ${machineId}`);
2176
+ const url = `${this.apiBaseUrl}/api/v1/project/machines/${machineId}/render?game_id=${gameId}`;
2177
+ const response = await fetch(url, {
2178
+ headers: {
2179
+ Authorization: `Bearer ${this.jwtToken}`
2180
+ }
2181
+ });
2182
+ if (!response.ok) {
2183
+ const errorText = await response.text();
2184
+ throw new Error(`Machine render request failed: ${response.status} ${errorText}`);
2185
+ }
2186
+ const html = await response.text();
2187
+ logger.info(`Machine render fetched successfully for machine: ${machineId}`);
2188
+ return html;
2189
+ }
2155
2190
  };
2156
2191
  export {
2157
2192
  AdsService,
package/dist/react.d.mts CHANGED
@@ -41,6 +41,8 @@ interface Inventory {
41
41
  type GameDataValue = string | number | boolean | null | GameDataValue[] | {
42
42
  [key: string]: GameDataValue;
43
43
  };
44
+ /** Atomic operation type for persistent game data */
45
+ type GameDataOperation = 'set' | 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'min' | 'max' | 'append';
44
46
  /** Single game data item with metadata */
45
47
  interface GameDataItem {
46
48
  key: string;
@@ -48,15 +50,36 @@ interface GameDataItem {
48
50
  created_at: string;
49
51
  updated_at: string;
50
52
  }
51
- /** Response from save operations */
53
+ /** Response from a single save operation */
52
54
  interface SaveGameDataResponse {
53
55
  success: boolean;
54
56
  message: string;
57
+ /** Resulting value after an atomic operation (only present when operation is used) */
58
+ result?: GameDataValue;
59
+ }
60
+ /** Per-item result in a batch save response */
61
+ interface BatchSaveResultItem {
62
+ key: string;
63
+ success: boolean;
64
+ /** Resulting value after an atomic operation */
65
+ result?: GameDataValue;
66
+ error?: string;
67
+ }
68
+ /** Response from a batch save operation */
69
+ interface BatchSaveGameDataResponse {
70
+ success: boolean;
71
+ message: string;
72
+ /** Per-item results (present when any item uses an operation) */
73
+ results?: BatchSaveResultItem[];
55
74
  }
56
75
  /** Batch item for saving multiple entries */
57
76
  interface GameDataBatchItem {
58
77
  key: string;
59
78
  value: GameDataValue;
79
+ /** Atomic operation to perform on the value */
80
+ operation?: GameDataOperation;
81
+ /** Dot-notation path targeting a nested field (e.g. "stats.score") */
82
+ path?: string;
60
83
  }
61
84
 
62
85
  /**
@@ -297,17 +320,19 @@ declare class HyveClient {
297
320
  * Save persistent game data
298
321
  * @param key Data key
299
322
  * @param value Data value (any JSON-serializable value)
323
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
324
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
300
325
  * @param storage Storage mode override ('cloud' or 'local')
301
326
  * @returns Promise resolving to save response
302
327
  */
303
- saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
328
+ saveGameData(key: string, value: GameDataValue, operation?: GameDataOperation, path?: string, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
304
329
  /**
305
330
  * Batch save persistent game data
306
- * @param items Array of key-value pairs to save
331
+ * @param items Array of items to save (each may include an optional operation and path)
307
332
  * @param storage Storage mode override ('cloud' or 'local')
308
- * @returns Promise resolving to save response
333
+ * @returns Promise resolving to batch save response with per-item results
309
334
  */
310
- batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
335
+ batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<BatchSaveGameDataResponse>;
311
336
  /**
312
337
  * Get persistent game data
313
338
  * @param key Data key
@@ -415,6 +440,12 @@ declare class HyveClient {
415
440
  * Unmount Stripe checkout element
416
441
  */
417
442
  unmountBillingCheckout(): void;
443
+ /**
444
+ * Fetches the rendered HTML view for a project machine
445
+ * @param machineId The machine ID to render
446
+ * @returns Promise resolving to the rendered HTML string
447
+ */
448
+ getMachineRender(machineId: string): Promise<string>;
418
449
  }
419
450
 
420
451
  interface HyveSdkProviderProps {
package/dist/react.d.ts CHANGED
@@ -41,6 +41,8 @@ interface Inventory {
41
41
  type GameDataValue = string | number | boolean | null | GameDataValue[] | {
42
42
  [key: string]: GameDataValue;
43
43
  };
44
+ /** Atomic operation type for persistent game data */
45
+ type GameDataOperation = 'set' | 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'min' | 'max' | 'append';
44
46
  /** Single game data item with metadata */
45
47
  interface GameDataItem {
46
48
  key: string;
@@ -48,15 +50,36 @@ interface GameDataItem {
48
50
  created_at: string;
49
51
  updated_at: string;
50
52
  }
51
- /** Response from save operations */
53
+ /** Response from a single save operation */
52
54
  interface SaveGameDataResponse {
53
55
  success: boolean;
54
56
  message: string;
57
+ /** Resulting value after an atomic operation (only present when operation is used) */
58
+ result?: GameDataValue;
59
+ }
60
+ /** Per-item result in a batch save response */
61
+ interface BatchSaveResultItem {
62
+ key: string;
63
+ success: boolean;
64
+ /** Resulting value after an atomic operation */
65
+ result?: GameDataValue;
66
+ error?: string;
67
+ }
68
+ /** Response from a batch save operation */
69
+ interface BatchSaveGameDataResponse {
70
+ success: boolean;
71
+ message: string;
72
+ /** Per-item results (present when any item uses an operation) */
73
+ results?: BatchSaveResultItem[];
55
74
  }
56
75
  /** Batch item for saving multiple entries */
57
76
  interface GameDataBatchItem {
58
77
  key: string;
59
78
  value: GameDataValue;
79
+ /** Atomic operation to perform on the value */
80
+ operation?: GameDataOperation;
81
+ /** Dot-notation path targeting a nested field (e.g. "stats.score") */
82
+ path?: string;
60
83
  }
61
84
 
62
85
  /**
@@ -297,17 +320,19 @@ declare class HyveClient {
297
320
  * Save persistent game data
298
321
  * @param key Data key
299
322
  * @param value Data value (any JSON-serializable value)
323
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
324
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
300
325
  * @param storage Storage mode override ('cloud' or 'local')
301
326
  * @returns Promise resolving to save response
302
327
  */
303
- saveGameData(key: string, value: GameDataValue, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
328
+ saveGameData(key: string, value: GameDataValue, operation?: GameDataOperation, path?: string, storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
304
329
  /**
305
330
  * Batch save persistent game data
306
- * @param items Array of key-value pairs to save
331
+ * @param items Array of items to save (each may include an optional operation and path)
307
332
  * @param storage Storage mode override ('cloud' or 'local')
308
- * @returns Promise resolving to save response
333
+ * @returns Promise resolving to batch save response with per-item results
309
334
  */
310
- batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<SaveGameDataResponse>;
335
+ batchSaveGameData(items: GameDataBatchItem[], storage?: 'cloud' | 'local'): Promise<BatchSaveGameDataResponse>;
311
336
  /**
312
337
  * Get persistent game data
313
338
  * @param key Data key
@@ -415,6 +440,12 @@ declare class HyveClient {
415
440
  * Unmount Stripe checkout element
416
441
  */
417
442
  unmountBillingCheckout(): void;
443
+ /**
444
+ * Fetches the rendered HTML view for a project machine
445
+ * @param machineId The machine ID to render
446
+ * @returns Promise resolving to the rendered HTML string
447
+ */
448
+ getMachineRender(machineId: string): Promise<string>;
418
449
  }
419
450
 
420
451
  interface HyveSdkProviderProps {
package/dist/react.js CHANGED
@@ -1384,13 +1384,19 @@ var CloudStorageAdapter = class {
1384
1384
  constructor(callApi) {
1385
1385
  this.callApi = callApi;
1386
1386
  }
1387
- async saveGameData(gameId, key, value) {
1387
+ async saveGameData(gameId, key, value, operation, path) {
1388
1388
  return this.callApi("/api/v1/persistent-game-data", {
1389
1389
  method: "POST",
1390
1390
  headers: {
1391
1391
  "Content-Type": "application/json"
1392
1392
  },
1393
- body: JSON.stringify({ game_id: gameId, key, value })
1393
+ body: JSON.stringify({
1394
+ game_id: gameId,
1395
+ key,
1396
+ value,
1397
+ ...operation !== void 0 && { operation },
1398
+ ...path !== void 0 && { path }
1399
+ })
1394
1400
  });
1395
1401
  }
1396
1402
  async batchSaveGameData(gameId, items) {
@@ -1460,7 +1466,7 @@ var LocalStorageAdapter = class {
1460
1466
  getStorageKey(gameId, key) {
1461
1467
  return `${this.storagePrefix}:${gameId}:${key}`;
1462
1468
  }
1463
- async saveGameData(gameId, key, value) {
1469
+ async saveGameData(gameId, key, value, _operation, _path) {
1464
1470
  try {
1465
1471
  const storageKey = this.getStorageKey(gameId, key);
1466
1472
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -1892,23 +1898,25 @@ var HyveClient = class {
1892
1898
  * Save persistent game data
1893
1899
  * @param key Data key
1894
1900
  * @param value Data value (any JSON-serializable value)
1901
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
1902
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
1895
1903
  * @param storage Storage mode override ('cloud' or 'local')
1896
1904
  * @returns Promise resolving to save response
1897
1905
  */
1898
- async saveGameData(key, value, storage) {
1906
+ async saveGameData(key, value, operation, path, storage) {
1899
1907
  const gameId = this.requireGameId();
1900
1908
  const storageMode = storage || this.storageMode;
1901
1909
  logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
1902
1910
  const adapter = this.getStorageAdapter(storage);
1903
- const response = await adapter.saveGameData(gameId, key, value);
1911
+ const response = await adapter.saveGameData(gameId, key, value, operation, path);
1904
1912
  logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
1905
1913
  return response;
1906
1914
  }
1907
1915
  /**
1908
1916
  * Batch save persistent game data
1909
- * @param items Array of key-value pairs to save
1917
+ * @param items Array of items to save (each may include an optional operation and path)
1910
1918
  * @param storage Storage mode override ('cloud' or 'local')
1911
- * @returns Promise resolving to save response
1919
+ * @returns Promise resolving to batch save response with per-item results
1912
1920
  */
1913
1921
  async batchSaveGameData(items, storage) {
1914
1922
  const gameId = this.requireGameId();
@@ -2143,6 +2151,33 @@ var HyveClient = class {
2143
2151
  unmountBillingCheckout() {
2144
2152
  this.billingService.unmountCheckoutElement();
2145
2153
  }
2154
+ /**
2155
+ * Fetches the rendered HTML view for a project machine
2156
+ * @param machineId The machine ID to render
2157
+ * @returns Promise resolving to the rendered HTML string
2158
+ */
2159
+ async getMachineRender(machineId) {
2160
+ if (!this.jwtToken) {
2161
+ throw new Error(
2162
+ "No JWT token available. Ensure hyve-access and game-id are present in the URL."
2163
+ );
2164
+ }
2165
+ const gameId = this.requireGameId();
2166
+ logger.debug(`Fetching machine render for machine: ${machineId}`);
2167
+ const url = `${this.apiBaseUrl}/api/v1/project/machines/${machineId}/render?game_id=${gameId}`;
2168
+ const response = await fetch(url, {
2169
+ headers: {
2170
+ Authorization: `Bearer ${this.jwtToken}`
2171
+ }
2172
+ });
2173
+ if (!response.ok) {
2174
+ const errorText = await response.text();
2175
+ throw new Error(`Machine render request failed: ${response.status} ${errorText}`);
2176
+ }
2177
+ const html = await response.text();
2178
+ logger.info(`Machine render fetched successfully for machine: ${machineId}`);
2179
+ return html;
2180
+ }
2146
2181
  };
2147
2182
 
2148
2183
  // src/react.tsx
package/dist/react.mjs CHANGED
@@ -1363,13 +1363,19 @@ var CloudStorageAdapter = class {
1363
1363
  constructor(callApi) {
1364
1364
  this.callApi = callApi;
1365
1365
  }
1366
- async saveGameData(gameId, key, value) {
1366
+ async saveGameData(gameId, key, value, operation, path) {
1367
1367
  return this.callApi("/api/v1/persistent-game-data", {
1368
1368
  method: "POST",
1369
1369
  headers: {
1370
1370
  "Content-Type": "application/json"
1371
1371
  },
1372
- body: JSON.stringify({ game_id: gameId, key, value })
1372
+ body: JSON.stringify({
1373
+ game_id: gameId,
1374
+ key,
1375
+ value,
1376
+ ...operation !== void 0 && { operation },
1377
+ ...path !== void 0 && { path }
1378
+ })
1373
1379
  });
1374
1380
  }
1375
1381
  async batchSaveGameData(gameId, items) {
@@ -1439,7 +1445,7 @@ var LocalStorageAdapter = class {
1439
1445
  getStorageKey(gameId, key) {
1440
1446
  return `${this.storagePrefix}:${gameId}:${key}`;
1441
1447
  }
1442
- async saveGameData(gameId, key, value) {
1448
+ async saveGameData(gameId, key, value, _operation, _path) {
1443
1449
  try {
1444
1450
  const storageKey = this.getStorageKey(gameId, key);
1445
1451
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -1871,23 +1877,25 @@ var HyveClient = class {
1871
1877
  * Save persistent game data
1872
1878
  * @param key Data key
1873
1879
  * @param value Data value (any JSON-serializable value)
1880
+ * @param operation Optional atomic operation (e.g. 'add', 'max', 'append')
1881
+ * @param path Optional dot-notation path to a nested field (e.g. 'stats.score')
1874
1882
  * @param storage Storage mode override ('cloud' or 'local')
1875
1883
  * @returns Promise resolving to save response
1876
1884
  */
1877
- async saveGameData(key, value, storage) {
1885
+ async saveGameData(key, value, operation, path, storage) {
1878
1886
  const gameId = this.requireGameId();
1879
1887
  const storageMode = storage || this.storageMode;
1880
1888
  logger.debug(`Saving game data to ${storageMode}: ${gameId}/${key}`);
1881
1889
  const adapter = this.getStorageAdapter(storage);
1882
- const response = await adapter.saveGameData(gameId, key, value);
1890
+ const response = await adapter.saveGameData(gameId, key, value, operation, path);
1883
1891
  logger.info(`Game data saved successfully to ${storageMode}: ${gameId}/${key}`);
1884
1892
  return response;
1885
1893
  }
1886
1894
  /**
1887
1895
  * Batch save persistent game data
1888
- * @param items Array of key-value pairs to save
1896
+ * @param items Array of items to save (each may include an optional operation and path)
1889
1897
  * @param storage Storage mode override ('cloud' or 'local')
1890
- * @returns Promise resolving to save response
1898
+ * @returns Promise resolving to batch save response with per-item results
1891
1899
  */
1892
1900
  async batchSaveGameData(items, storage) {
1893
1901
  const gameId = this.requireGameId();
@@ -2122,6 +2130,33 @@ var HyveClient = class {
2122
2130
  unmountBillingCheckout() {
2123
2131
  this.billingService.unmountCheckoutElement();
2124
2132
  }
2133
+ /**
2134
+ * Fetches the rendered HTML view for a project machine
2135
+ * @param machineId The machine ID to render
2136
+ * @returns Promise resolving to the rendered HTML string
2137
+ */
2138
+ async getMachineRender(machineId) {
2139
+ if (!this.jwtToken) {
2140
+ throw new Error(
2141
+ "No JWT token available. Ensure hyve-access and game-id are present in the URL."
2142
+ );
2143
+ }
2144
+ const gameId = this.requireGameId();
2145
+ logger.debug(`Fetching machine render for machine: ${machineId}`);
2146
+ const url = `${this.apiBaseUrl}/api/v1/project/machines/${machineId}/render?game_id=${gameId}`;
2147
+ const response = await fetch(url, {
2148
+ headers: {
2149
+ Authorization: `Bearer ${this.jwtToken}`
2150
+ }
2151
+ });
2152
+ if (!response.ok) {
2153
+ const errorText = await response.text();
2154
+ throw new Error(`Machine render request failed: ${response.status} ${errorText}`);
2155
+ }
2156
+ const html = await response.text();
2157
+ logger.info(`Machine render fetched successfully for machine: ${machineId}`);
2158
+ return html;
2159
+ }
2125
2160
  };
2126
2161
 
2127
2162
  // src/react.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyve-sdk/js",
3
- "version": "2.1.2",
3
+ "version": "2.3.0",
4
4
  "description": "Hyve SDK - TypeScript wrapper for Hyve game server integration",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -27,6 +27,14 @@
27
27
  "README.md",
28
28
  "LICENSE"
29
29
  ],
30
+ "scripts": {
31
+ "lint": "eslint . --max-warnings 0",
32
+ "check-types": "tsc --noEmit",
33
+ "build": "tsup",
34
+ "prepublishOnly": "pnpm run build && pnpm run check-types",
35
+ "publish:npm": "pnpm publish --access public",
36
+ "publish:dry-run": "pnpm publish --dry-run --access public --no-git-checks"
37
+ },
30
38
  "keywords": [
31
39
  "hyve",
32
40
  "game",
@@ -63,19 +71,12 @@
63
71
  }
64
72
  },
65
73
  "devDependencies": {
74
+ "@repo/eslint-config": "workspace:*",
75
+ "@repo/typescript-config": "workspace:*",
66
76
  "@types/minimatch": "^5.1.2",
67
77
  "@types/react": "^18.3.28",
68
78
  "@types/uuid": "^10.0.0",
69
79
  "tsup": "^8.4.0",
70
- "typescript": "^5.3.3",
71
- "@repo/typescript-config": "0.0.0",
72
- "@repo/eslint-config": "0.0.0"
73
- },
74
- "scripts": {
75
- "lint": "eslint . --max-warnings 0",
76
- "check-types": "tsc --noEmit",
77
- "build": "tsup",
78
- "publish:npm": "pnpm publish --access public",
79
- "publish:dry-run": "pnpm publish --dry-run --access public --no-git-checks"
80
+ "typescript": "^5.3.3"
80
81
  }
81
- }
82
+ }