@series-inc/venus-sdk 3.1.2 → 3.2.1-beta.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.
Files changed (38) hide show
  1. package/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-or6zfdzM.d.mts} +499 -293
  2. package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-or6zfdzM.d.ts} +499 -293
  3. package/dist/chunk-NSSMTXJJ.mjs +7 -0
  4. package/dist/chunk-NSSMTXJJ.mjs.map +1 -0
  5. package/dist/{chunk-W7IPHM67.mjs → chunk-QABXMFND.mjs} +3 -26
  6. package/dist/chunk-QABXMFND.mjs.map +1 -0
  7. package/dist/chunk-UXY5CKKG.mjs +12 -0
  8. package/dist/chunk-UXY5CKKG.mjs.map +1 -0
  9. package/dist/{chunk-PXWCNWJ6.mjs → chunk-YOBDYPKZ.mjs} +1528 -1577
  10. package/dist/chunk-YOBDYPKZ.mjs.map +1 -0
  11. package/dist/core-62LWDHN7.mjs +4 -0
  12. package/dist/{core-R3FHW62G.mjs.map → core-62LWDHN7.mjs.map} +1 -1
  13. package/dist/index.cjs +1556 -1585
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.mts +290 -92
  16. package/dist/index.d.ts +290 -92
  17. package/dist/index.mjs +4 -6
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/venus-api/index.cjs +1613 -2008
  20. package/dist/venus-api/index.cjs.map +1 -1
  21. package/dist/venus-api/index.d.mts +2 -2
  22. package/dist/venus-api/index.d.ts +2 -2
  23. package/dist/venus-api/index.mjs +92 -391
  24. package/dist/venus-api/index.mjs.map +1 -1
  25. package/dist/vite/index.cjs +534 -0
  26. package/dist/vite/index.cjs.map +1 -0
  27. package/dist/vite/index.mjs +527 -0
  28. package/dist/vite/index.mjs.map +1 -0
  29. package/dist/webview/index.cjs +15 -0
  30. package/dist/webview/index.cjs.map +1 -0
  31. package/dist/webview/index.d.mts +15 -0
  32. package/dist/webview/index.d.ts +15 -0
  33. package/dist/webview/index.mjs +4 -0
  34. package/dist/webview/index.mjs.map +1 -0
  35. package/package.json +1 -1
  36. package/dist/chunk-PXWCNWJ6.mjs.map +0 -1
  37. package/dist/chunk-W7IPHM67.mjs.map +0 -1
  38. package/dist/core-R3FHW62G.mjs +0 -3
@@ -1,9 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
6
  var __esm = (fn, res) => function __init() {
9
7
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -12,15 +10,6 @@ var __export = (target, all) => {
12
10
  for (var name in all)
13
11
  __defProp(target, name, { get: all[name], enumerable: true });
14
12
  };
15
- var __copyProps = (to, from, except, desc) => {
16
- if (from && typeof from === "object" || typeof from === "function") {
17
- for (let key of __getOwnPropNames(from))
18
- if (!__hasOwnProp.call(to, key) && key !== except)
19
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
- }
21
- return to;
22
- };
23
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
13
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
25
14
 
26
15
  // src/venus-api/systems/core.js
@@ -111,237 +100,24 @@ var init_core = __esm({
111
100
  }
112
101
  });
113
102
 
114
- // src/rooms/RoomsApi.ts
115
- var init_RoomsApi = __esm({
116
- "src/rooms/RoomsApi.ts"() {
117
- }
118
- });
119
-
120
- // src/rooms/VenusRoom.ts
121
- var VenusRoom;
122
- var init_VenusRoom = __esm({
123
- "src/rooms/VenusRoom.ts"() {
124
- VenusRoom = class {
125
- constructor(roomData) {
126
- __publicField(this, "id");
127
- __publicField(this, "name");
128
- __publicField(this, "players");
129
- __publicField(this, "maxPlayers");
130
- __publicField(this, "gameType");
131
- __publicField(this, "appId");
132
- __publicField(this, "type");
133
- __publicField(this, "createdBy");
134
- __publicField(this, "createdAt");
135
- __publicField(this, "updatedAt");
136
- __publicField(this, "isPrivate");
137
- __publicField(this, "currentPlayers");
138
- __publicField(this, "status");
139
- __publicField(this, "customMetadata");
140
- __publicField(this, "admins");
141
- __publicField(this, "roomCode");
142
- __publicField(this, "description");
143
- __publicField(this, "data");
144
- __publicField(this, "version");
145
- __publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
146
- this.id = roomData.id;
147
- this.name = roomData.name;
148
- this.players = roomData.currentPlayers || [];
149
- this.maxPlayers = roomData.maxPlayers;
150
- this.gameType = roomData.gameType;
151
- this.appId = roomData.appId;
152
- this.type = roomData.type;
153
- this.createdBy = roomData.createdBy;
154
- this.createdAt = roomData.createdAt;
155
- this.updatedAt = roomData.updatedAt;
156
- this.isPrivate = roomData.isPrivate;
157
- this.currentPlayers = roomData.currentPlayers || [];
158
- this.status = roomData.status;
159
- this.customMetadata = roomData.customMetadata || {};
160
- this.admins = roomData.admins || [];
161
- this.roomCode = roomData.roomCode;
162
- this.description = roomData.description;
163
- this.data = roomData.data || {};
164
- this.version = roomData.version;
165
- console.log(`VenusRoom: Created room object for ${this.id}`, {
166
- hasCustomMetadata: !!this.customMetadata,
167
- hasGameState: !!this.customMetadata?.rules?.gameState,
168
- gamePhase: this.customMetadata?.rules?.gameState?.phase,
169
- currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
170
- });
171
- }
172
- updateFromRoomData(newRoomData) {
173
- if (newRoomData.id === this.id) {
174
- this.name = newRoomData.name || this.name;
175
- this.players = newRoomData.currentPlayers || this.players;
176
- this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
177
- this.gameType = newRoomData.gameType || this.gameType;
178
- this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
179
- this.customMetadata = newRoomData.customMetadata || this.customMetadata;
180
- this.data = newRoomData.data || this.data;
181
- this.status = newRoomData.status || this.status;
182
- this.updatedAt = newRoomData.updatedAt || this.updatedAt;
183
- console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
184
- hasCustomMetadata: !!this.customMetadata,
185
- hasGameState: !!this.customMetadata?.rules?.gameState,
186
- gamePhase: this.customMetadata?.rules?.gameState?.phase,
187
- currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
188
- });
189
- }
190
- }
191
- };
192
- }
193
- });
194
-
195
- // src/rooms/index.ts
196
- var rooms_exports = {};
197
- __export(rooms_exports, {
198
- VenusRoom: () => VenusRoom,
199
- initializeRoomsApi: () => initializeRoomsApi,
200
- setupRoomNotifications: () => setupRoomNotifications
201
- });
202
- function bindMethod(target, targetKey, source, sourceKey) {
203
- const key = sourceKey ?? targetKey;
204
- const fn = source?.[key];
205
- if (typeof fn === "function") {
206
- target[targetKey] = fn.bind(source);
207
- return true;
208
- }
209
- return false;
210
- }
211
- function setupRoomNotifications(transport, getSubscriptions) {
212
- console.log("[Venus Rooms] Setting up room notification listeners");
213
- return transport.onVenusMessage((message) => {
214
- const subscriptions = getSubscriptions();
215
- if (!subscriptions) {
216
- return;
217
- }
218
- if (message.type === "H5_ROOM_DATA_UPDATED") {
219
- const messageData = message.data;
220
- const { roomId, roomData } = messageData;
221
- if (!roomId) return;
222
- const callbacks = subscriptions.data?.[roomId] || [];
223
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
224
- console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
225
- callbacks.forEach((callback) => {
226
- try {
227
- callback(roomData);
228
- } catch (error) {
229
- console.error("[Venus Rooms] Error in room data callback:", error);
230
- throw error;
231
- }
232
- });
233
- allEventsCallbacks.forEach((callback) => {
234
- try {
235
- callback({ type: message.type, ...messageData });
236
- } catch (error) {
237
- console.error("[Venus Rooms] Error in allEvents callback:", error);
238
- throw error;
239
- }
240
- });
241
- }
242
- if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
243
- const messageData = message.data;
244
- const { roomId } = messageData;
245
- if (!roomId) return;
246
- const callbacks = subscriptions.messages?.[roomId] || [];
247
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
248
- console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
249
- callbacks.forEach((callback) => {
250
- try {
251
- callback(messageData);
252
- } catch (error) {
253
- console.error("[Venus Rooms] Error in room message callback:", error);
254
- throw error;
255
- }
256
- });
257
- allEventsCallbacks.forEach((callback) => {
258
- try {
259
- callback({ type: message.type, ...messageData });
260
- } catch (error) {
261
- console.error("[Venus Rooms] Error in allEvents callback:", error);
262
- throw error;
263
- }
264
- });
265
- }
266
- if (message.type === "app:h5:proposedMoveValidationUpdated") {
267
- const messageData = message.data;
268
- const { roomId } = messageData;
269
- if (!roomId) return;
270
- const callbacks = subscriptions.gameEvents?.[roomId] || [];
271
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
272
- console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
273
- callbacks.forEach((callback) => {
274
- try {
275
- callback(messageData);
276
- } catch (error) {
277
- console.error("[Venus Rooms] Error in game event callback:", error);
278
- throw error;
279
- }
280
- });
281
- allEventsCallbacks.forEach((callback) => {
282
- try {
283
- callback({ type: message.type, ...messageData });
284
- } catch (error) {
285
- console.error("[Venus Rooms] Error in allEvents callback:", error);
286
- throw error;
287
- }
288
- });
289
- }
290
- });
291
- }
292
- function initializeRoomsApi(venusApi, host) {
293
- const roomsApi = host?.rooms;
294
- if (!roomsApi) {
295
- console.warn(
296
- "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
297
- );
298
- return;
299
- }
300
- const venus = venusApi;
301
- const existingNamespace = venus.rooms || {};
302
- const roomsNamespace = Object.assign({}, existingNamespace);
303
- const namespaceBindings = [
304
- ["create", "createRoom"],
305
- ["joinOrCreate", "joinOrCreateRoom"],
306
- ["joinByCode", "joinRoomByCode"],
307
- ["list", "getUserRooms"],
308
- ["subscribeToRoom", "subscribe"],
309
- ["updateRoomData", "updateData"],
310
- ["getRoomData", "getData"],
311
- ["sendRoomMessage", "sendMessage"],
312
- ["leaveRoom", "leave"],
313
- ["startRoomGame", "startGame"],
314
- ["proposeMove"],
315
- ["validateMove"]
316
- ];
317
- namespaceBindings.forEach(([targetKey, sourceKey]) => {
318
- bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
319
- });
320
- venus.rooms = roomsNamespace;
321
- }
322
- var init_rooms = __esm({
323
- "src/rooms/index.ts"() {
324
- init_RoomsApi();
325
- init_VenusRoom();
326
- }
327
- });
328
-
329
103
  // src/storage/MockStorageApi.ts
104
+ var STORAGE_PREFIXES = {
105
+ globalStorage: "venus:global",
106
+ deviceCache: "venus:deviceCache",
107
+ appStorage: "venus:appStorage"
108
+ };
330
109
  function createMockStorageApi(storageType, appUrl) {
331
110
  const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
332
- let prefix;
111
+ let prefix = STORAGE_PREFIXES[storageType];
333
112
  let syncDelay = 0;
334
113
  switch (storageType) {
335
114
  case "deviceCache":
336
- prefix = "venus:app";
337
115
  syncDelay = 0;
338
116
  break;
339
117
  case "appStorage":
340
- prefix = "venus:app";
341
118
  syncDelay = 100;
342
119
  break;
343
120
  case "globalStorage":
344
- prefix = "venus:global";
345
121
  syncDelay = 100;
346
122
  break;
347
123
  default:
@@ -354,29 +130,38 @@ var MockStorageApi = class {
354
130
  constructor(prefix, syncDelay) {
355
131
  __publicField(this, "prefix");
356
132
  __publicField(this, "syncDelay");
133
+ __publicField(this, "orderStorageKey");
357
134
  this.prefix = prefix;
358
135
  this.syncDelay = syncDelay;
136
+ this.orderStorageKey = `${prefix}__order__`;
359
137
  }
360
138
  async clear() {
139
+ const keysToRemove = [];
361
140
  const fullLength = localStorage.length;
362
141
  for (let i = 0; i < fullLength; i++) {
363
142
  const fullKey = localStorage.key(i);
364
- if (fullKey && fullKey.startsWith(this.prefix)) {
365
- localStorage.removeItem(fullKey);
143
+ if (!fullKey || fullKey === this.orderStorageKey) {
144
+ continue;
366
145
  }
146
+ if (fullKey.startsWith(this.prefix)) {
147
+ keysToRemove.push(fullKey);
148
+ }
149
+ }
150
+ for (const key of keysToRemove) {
151
+ localStorage.removeItem(key);
367
152
  }
153
+ this.clearOrder();
368
154
  await this.simulateSyncDelay();
369
155
  }
370
156
  async getAllItems() {
371
157
  const items = new Array();
372
- const fullLength = localStorage.length;
373
- for (let i = 0; i < fullLength; i++) {
374
- const fullKey = localStorage.key(i);
375
- if (fullKey && fullKey.startsWith(this.prefix)) {
376
- const item = localStorage.getItem(fullKey);
377
- if (item) {
378
- items.push(item);
379
- }
158
+ const orderedKeys = this.keys();
159
+ for (const key of orderedKeys) {
160
+ const value = localStorage.getItem(this.buildKey(key));
161
+ if (value !== null) {
162
+ items.push(value);
163
+ } else {
164
+ this.removeFromOrder(key);
380
165
  }
381
166
  }
382
167
  return items;
@@ -401,11 +186,13 @@ var MockStorageApi = class {
401
186
  const fullKey = this.buildKey(key);
402
187
  await this.simulateSyncDelay();
403
188
  localStorage.removeItem(fullKey);
189
+ this.removeFromOrder(key);
404
190
  }
405
191
  async setItem(key, item) {
406
192
  const fullKey = this.buildKey(key);
407
193
  await this.simulateSyncDelay();
408
194
  localStorage.setItem(fullKey, item);
195
+ this.upsertOrder(key);
409
196
  }
410
197
  async setMultipleItems(entries) {
411
198
  for (const entry of entries) {
@@ -413,6 +200,7 @@ var MockStorageApi = class {
413
200
  localStorage.setItem(fullKey, entry.value);
414
201
  }
415
202
  await this.simulateSyncDelay();
203
+ this.bulkUpsertOrder(entries.map((entry) => entry.key));
416
204
  }
417
205
  async removeMultipleItems(keys) {
418
206
  for (const key of keys) {
@@ -420,6 +208,7 @@ var MockStorageApi = class {
420
208
  localStorage.removeItem(fullKey);
421
209
  }
422
210
  await this.simulateSyncDelay();
211
+ this.bulkRemoveFromOrder(keys);
423
212
  }
424
213
  buildKey(key) {
425
214
  const prefix = this.prefix;
@@ -430,17 +219,8 @@ var MockStorageApi = class {
430
219
  return fullKey.substring(prefix.length);
431
220
  }
432
221
  keys() {
433
- const keys = new Array();
434
- let length = localStorage.length;
435
- for (let i = 0; i < length; i++) {
436
- const fullKey = localStorage.key(i);
437
- if (fullKey && fullKey.startsWith(this.prefix)) {
438
- length++;
439
- const key = this.extractKey(fullKey);
440
- keys.push(key);
441
- }
442
- }
443
- return keys;
222
+ const order = this.readOrder();
223
+ return [...order];
444
224
  }
445
225
  async simulateSyncDelay() {
446
226
  const syncDelay = this.syncDelay;
@@ -448,6 +228,127 @@ var MockStorageApi = class {
448
228
  await new Promise((resolve) => setTimeout(resolve, syncDelay));
449
229
  }
450
230
  }
231
+ readOrder() {
232
+ const raw = localStorage.getItem(this.orderStorageKey);
233
+ if (!raw) {
234
+ return this.rebuildOrderFromStorage();
235
+ }
236
+ try {
237
+ const parsed = JSON.parse(raw);
238
+ if (Array.isArray(parsed)) {
239
+ return this.normalizeOrder(parsed);
240
+ }
241
+ } catch {
242
+ }
243
+ return this.rebuildOrderFromStorage();
244
+ }
245
+ normalizeOrder(order) {
246
+ const seen = /* @__PURE__ */ new Set();
247
+ const normalized = [];
248
+ let changed = false;
249
+ for (const entry of order) {
250
+ if (typeof entry !== "string") {
251
+ changed = true;
252
+ continue;
253
+ }
254
+ if (seen.has(entry)) {
255
+ changed = true;
256
+ continue;
257
+ }
258
+ const fullKey = this.buildKey(entry);
259
+ if (localStorage.getItem(fullKey) === null) {
260
+ changed = true;
261
+ continue;
262
+ }
263
+ seen.add(entry);
264
+ normalized.push(entry);
265
+ }
266
+ if (changed) {
267
+ this.writeOrder(normalized);
268
+ }
269
+ return normalized;
270
+ }
271
+ rebuildOrderFromStorage() {
272
+ const keys = [];
273
+ const total = localStorage.length;
274
+ for (let i = 0; i < total; i++) {
275
+ const fullKey = localStorage.key(i);
276
+ if (!fullKey) continue;
277
+ if (fullKey === this.orderStorageKey) continue;
278
+ if (fullKey.startsWith(this.prefix)) {
279
+ keys.push(this.extractKey(fullKey));
280
+ }
281
+ }
282
+ this.writeOrder(keys);
283
+ return keys;
284
+ }
285
+ upsertOrder(key) {
286
+ const order = this.readOrder();
287
+ const index = order.indexOf(key);
288
+ if (index !== -1) {
289
+ order.splice(index, 1);
290
+ }
291
+ order.push(key);
292
+ this.writeOrder(order);
293
+ }
294
+ bulkUpsertOrder(keys) {
295
+ const dedupedKeys = this.dedupeKeys(keys);
296
+ if (dedupedKeys.length === 0) {
297
+ return;
298
+ }
299
+ const order = this.readOrder();
300
+ const keysSet = new Set(dedupedKeys);
301
+ const filtered = order.filter((entry) => !keysSet.has(entry));
302
+ for (const key of dedupedKeys) {
303
+ filtered.push(key);
304
+ }
305
+ this.writeOrder(filtered);
306
+ }
307
+ removeFromOrder(key) {
308
+ const order = this.readOrder();
309
+ const index = order.indexOf(key);
310
+ if (index !== -1) {
311
+ order.splice(index, 1);
312
+ this.writeOrder(order);
313
+ }
314
+ }
315
+ bulkRemoveFromOrder(keys) {
316
+ const dedupedKeys = this.dedupeKeys(keys);
317
+ if (dedupedKeys.length === 0) {
318
+ return;
319
+ }
320
+ const order = this.readOrder();
321
+ const keysSet = new Set(dedupedKeys);
322
+ const filtered = order.filter((entry) => !keysSet.has(entry));
323
+ if (filtered.length !== order.length) {
324
+ this.writeOrder(filtered);
325
+ }
326
+ }
327
+ writeOrder(order) {
328
+ if (order.length === 0) {
329
+ localStorage.removeItem(this.orderStorageKey);
330
+ return;
331
+ }
332
+ localStorage.setItem(this.orderStorageKey, JSON.stringify(order));
333
+ }
334
+ clearOrder() {
335
+ localStorage.removeItem(this.orderStorageKey);
336
+ }
337
+ dedupeKeys(keys) {
338
+ const result = [];
339
+ const seen = /* @__PURE__ */ new Set();
340
+ for (const key of keys) {
341
+ if (typeof key !== "string") {
342
+ continue;
343
+ }
344
+ if (seen.has(key)) {
345
+ continue;
346
+ }
347
+ seen.add(key);
348
+ result.push(key);
349
+ }
350
+ return result;
351
+ }
451
352
  };
452
353
  function generateAppIdentifier(appUrl) {
453
354
  if (!appUrl) appUrl = "";
@@ -635,190 +536,6 @@ function initializeAds(venusApiInstance, host) {
635
536
  venusApiInstance.ads = host.ads;
636
537
  }
637
538
 
638
- // src/venus-api/systems/theme.js
639
- init_core();
640
- var DEFAULT_TYPOGRAPHY = {
641
- fontFamily: {
642
- base: "Plus Jakarta Sans, Roboto, sans-serif",
643
- heading: "Plus Jakarta Sans, Roboto, sans-serif",
644
- mono: "monospace"
645
- },
646
- fontSize: {
647
- "2xs": "10px",
648
- xs: "12px",
649
- sm: "14px",
650
- md: "16px",
651
- lg: "18px",
652
- xl: "20px",
653
- "2xl": "24px",
654
- "3xl": "30px",
655
- "4xl": "36px",
656
- "5xl": "48px",
657
- "6xl": "60px"
658
- },
659
- fontWeight: {
660
- thin: "100",
661
- extralight: "200",
662
- light: "300",
663
- regular: "400",
664
- medium: "500",
665
- semibold: "600",
666
- bold: "700",
667
- extrabold: "800",
668
- black: "900",
669
- extrablack: "950"
670
- },
671
- lineHeight: {
672
- none: "1",
673
- tight: "1.25",
674
- snug: "1.375",
675
- normal: "1.5",
676
- relaxed: "1.625",
677
- loose: "2"
678
- }
679
- };
680
- var DEFAULT_THEME = {
681
- background: {
682
- default: "#131419",
683
- // Dark background
684
- muted: "#1b1d25",
685
- // Mid-dark background
686
- dark: "#0d0e11"
687
- // Darker background
688
- },
689
- text: {
690
- primary: "#ffffff",
691
- // White
692
- muted: "#808080",
693
- // Gray
694
- inverted: "#000000"
695
- // Black
696
- },
697
- theme: {
698
- primary: "#f6c833",
699
- // Different yellow for testing (slightly lighter)
700
- secondary: "#6366f1",
701
- // Different secondary for testing (purple)
702
- background: "#131419",
703
- // Dark background
704
- border: "#262626",
705
- // Dark border
706
- card: "#1b1d25",
707
- // Dark card
708
- "card-glass": "rgba(27, 29, 37, 0.8)"
709
- // Translucent dark card
710
- },
711
- typography: DEFAULT_TYPOGRAPHY
712
- };
713
- function initializeTheme(venusApiInstance) {
714
- if (!venusApiInstance._mock.theme) {
715
- venusApiInstance._mock.theme = DEFAULT_THEME;
716
- }
717
- if (!venusApiInstance._mock.typography) {
718
- venusApiInstance._mock.typography = DEFAULT_TYPOGRAPHY;
719
- }
720
- if (!venusApiInstance._mock.safeArea) {
721
- venusApiInstance._mock.safeArea = { top: 0, bottom: 0, left: 0, right: 0 };
722
- }
723
- venusApiInstance.applyVenusThemeToCSS = function(theme) {
724
- if (!theme) return;
725
- const root = document.documentElement;
726
- if (theme.background) {
727
- if (theme.background.default)
728
- root.style.setProperty("--color-background", theme.background.default);
729
- if (theme.background.muted)
730
- root.style.setProperty(
731
- "--color-background-muted",
732
- theme.background.muted
733
- );
734
- if (theme.background.dark)
735
- root.style.setProperty(
736
- "--color-background-dark",
737
- theme.background.dark
738
- );
739
- }
740
- if (theme.text) {
741
- if (theme.text.primary)
742
- root.style.setProperty("--color-text-primary", theme.text.primary);
743
- if (theme.text.muted)
744
- root.style.setProperty("--color-text-muted", theme.text.muted);
745
- }
746
- if (theme.theme) {
747
- if (theme.theme.primary)
748
- root.style.setProperty("--color-primary", theme.theme.primary);
749
- if (theme.theme.secondary)
750
- root.style.setProperty("--color-secondary", theme.theme.secondary);
751
- if (theme.theme.border)
752
- root.style.setProperty("--color-border", theme.theme.border);
753
- }
754
- if (theme.typography && theme.typography.fontFamily) {
755
- if (theme.typography.fontFamily.base) {
756
- root.style.setProperty(
757
- "--font-family",
758
- theme.typography.fontFamily.base
759
- );
760
- }
761
- }
762
- document.body.style.backgroundColor = root.style.getPropertyValue(
763
- "--color-background-dark"
764
- );
765
- };
766
- venusApiInstance.applyTheme = createProxiedMethod("applyTheme", function() {
767
- let apiTheme = null;
768
- apiTheme = this.config.theme;
769
- if (apiTheme) {
770
- this.applyVenusThemeToCSS(apiTheme);
771
- this.colors = {
772
- primary: apiTheme.theme?.primary || "#FF2877",
773
- secondary: apiTheme.theme?.secondary || "#4755FF",
774
- dark: apiTheme.background?.dark || "#0D0E11",
775
- darkLight: apiTheme.background?.muted || "#1B1D25",
776
- darkLighter: apiTheme.background?.default || "#23252F",
777
- textPrimary: apiTheme.text?.primary || "#FFFFFF",
778
- textMuted: apiTheme.text?.muted || "#808080",
779
- border: apiTheme.theme?.border || "#262626"
780
- };
781
- } else {
782
- this.colors = {
783
- primary: "#FF2877",
784
- secondary: "#4755FF",
785
- dark: "#0D0E11",
786
- darkLight: "#1B1D25",
787
- darkLighter: "#23252F",
788
- textPrimary: "#FFFFFF",
789
- textMuted: "#808080",
790
- border: "#262626"
791
- };
792
- }
793
- this.log("Theme applied successfully");
794
- });
795
- venusApiInstance.applySafeArea = createProxiedMethod("applySafeArea", function() {
796
- try {
797
- const safeArea = this.config.ui.safeArea;
798
- if (safeArea) {
799
- this.log("Applying safe area insets: " + JSON.stringify(safeArea));
800
- if (this.tapToStartScreen) {
801
- this.tapToStartScreen.style.marginTop = `${safeArea.top}px`;
802
- this.tapToStartScreen.style.marginBottom = `${safeArea.bottom}px`;
803
- }
804
- if (this.gameOverScreen) {
805
- this.gameOverScreen.style.marginTop = `${safeArea.top}px`;
806
- this.gameOverScreen.style.marginBottom = `${safeArea.bottom}px`;
807
- }
808
- if (this.maxScoreContainer) {
809
- this.maxScoreContainer.style.marginTop = `${safeArea.top}px`;
810
- this.maxScoreContainer.style.marginRight = `${safeArea.right}px`;
811
- }
812
- }
813
- } catch (error) {
814
- this.error("Error applying safe area: " + error.message);
815
- console.error("Error applying safe area:", error);
816
- }
817
- });
818
- venusApiInstance.DEFAULT_THEME = DEFAULT_THEME;
819
- venusApiInstance.DEFAULT_TYPOGRAPHY = DEFAULT_TYPOGRAPHY;
820
- }
821
-
822
539
  // src/popups/RpcPopupsApi.ts
823
540
  var RpcPopupsApi = class {
824
541
  constructor(rpcClient) {
@@ -971,13 +688,8 @@ var MockNotificationsApi = class {
971
688
  async cancelNotification(notificationId) {
972
689
  const venusApi = this.venusApi;
973
690
  if (isWebPlatform()) {
974
- console.log(
975
- "[Venus Mock] Cancel notification on web platform (simulated):",
976
- notificationId
977
- );
978
691
  return true;
979
692
  }
980
- console.log("[Venus Mock] Cancel local notification:", notificationId);
981
693
  await createMockDelay(MOCK_DELAYS.short);
982
694
  if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
983
695
  delete venusApi._mock.scheduledNotifications[notificationId];
@@ -987,12 +699,8 @@ var MockNotificationsApi = class {
987
699
  }
988
700
  async getAllScheduledLocalNotifications() {
989
701
  if (isWebPlatform()) {
990
- console.log(
991
- "[Venus Mock] Get notifications on web platform (returning empty list)"
992
- );
993
702
  return [];
994
703
  }
995
- console.log("[Venus Mock] Get all scheduled local notifications");
996
704
  await createMockDelay(MOCK_DELAYS.short);
997
705
  const venusApi = this.venusApi;
998
706
  const notifications = venusApi._mock.scheduledNotifications || {};
@@ -1000,10 +708,8 @@ var MockNotificationsApi = class {
1000
708
  }
1001
709
  async isLocalNotificationsEnabled() {
1002
710
  if (isWebPlatform()) {
1003
- console.log("[Venus Mock] Notifications not available on web platform");
1004
711
  return false;
1005
712
  }
1006
- console.log("[Venus Mock] Check if local notifications are enabled");
1007
713
  await createMockDelay(MOCK_DELAYS.short);
1008
714
  const venusApi = this.venusApi;
1009
715
  const isEnabled = venusApi._mock.notificationsEnabled !== false;
@@ -1012,9 +718,6 @@ var MockNotificationsApi = class {
1012
718
  async scheduleAsync(title, body, seconds, notificationId, options) {
1013
719
  const { priority = 50, groupId, payload } = options || {};
1014
720
  if (isWebPlatform()) {
1015
- console.log(
1016
- "[Venus Mock] Notifications not supported on web platform, simulating success"
1017
- );
1018
721
  console.info(
1019
722
  "\u{1F514} [Venus Mock] Notification would be scheduled:",
1020
723
  title || "Untitled",
@@ -1025,14 +728,11 @@ var MockNotificationsApi = class {
1025
728
  const mockId = `mock-web-notification-${Date.now()}`;
1026
729
  return mockId;
1027
730
  }
1028
- console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
1029
731
  const venusApi = this.venusApi;
1030
732
  if (!venusApi._mock.pendingRequests) {
1031
- console.log("[Venus Mock] Initializing pendingRequests");
1032
733
  venusApi._mock.pendingRequests = {};
1033
734
  }
1034
735
  const requestId = Date.now().toString();
1035
- console.log("[Venus Mock] Creating request with ID:", requestId);
1036
736
  return new Promise((resolve) => {
1037
737
  venusApi._mock.pendingRequests[requestId] = { resolve };
1038
738
  const id = notificationId || `mock-notification-${Date.now()}`;
@@ -1054,13 +754,8 @@ var MockNotificationsApi = class {
1054
754
  async setLocalNotificationsEnabled(enabled) {
1055
755
  const venusApi = this.venusApi;
1056
756
  if (isWebPlatform()) {
1057
- console.log(
1058
- "[Venus Mock] Set notifications enabled on web platform (simulated):",
1059
- enabled
1060
- );
1061
757
  return true;
1062
758
  }
1063
- console.log("[Venus Mock] Set local notifications enabled:", enabled);
1064
759
  await createMockDelay(MOCK_DELAYS.short);
1065
760
  venusApi._mock.notificationsEnabled = enabled;
1066
761
  return enabled;
@@ -1157,9 +852,11 @@ function isPacificDaylightTime(date) {
1157
852
 
1158
853
  // src/time/HostTimeApi.ts
1159
854
  var HostTimeApi = class {
1160
- constructor(rpcClient) {
855
+ constructor(rpcClient, venusApi) {
1161
856
  __publicField(this, "rpcClient");
857
+ __publicField(this, "venusApi");
1162
858
  this.rpcClient = rpcClient;
859
+ this.venusApi = venusApi;
1163
860
  }
1164
861
  async requestTimeAsync() {
1165
862
  const response = await this.rpcClient.call(
@@ -1169,13 +866,7 @@ var HostTimeApi = class {
1169
866
  return response;
1170
867
  }
1171
868
  formatTime(timestamp, options) {
1172
- let locale = "en-US";
1173
- const windowVenus = window.venus;
1174
- if (windowVenus._config.locale) {
1175
- locale = windowVenus._config.locale;
1176
- } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
1177
- locale = windowVenus._config.environment.browserInfo.language;
1178
- }
869
+ const locale = this.venusApi.getLocale();
1179
870
  const date = new Date(timestamp);
1180
871
  const dateTimeOptions = {
1181
872
  dateStyle: options.dateStyle || "medium",
@@ -1187,13 +878,7 @@ var HostTimeApi = class {
1187
878
  }
1188
879
  formatNumber(value, options) {
1189
880
  try {
1190
- let locale = "en-US";
1191
- const windowVenus = window.venus;
1192
- if (windowVenus._config.locale) {
1193
- locale = windowVenus._config.locale;
1194
- } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
1195
- locale = windowVenus._config.environment.browserInfo.language;
1196
- }
881
+ const locale = this.venusApi.getLocale();
1197
882
  const numberOptions = {
1198
883
  style: options?.style || "decimal",
1199
884
  minimumFractionDigits: options?.minimumFractionDigits || 0,
@@ -1257,18 +942,17 @@ var MockTimeApi = class {
1257
942
  this.venusApi = venusApi;
1258
943
  }
1259
944
  formatNumber(value, options) {
1260
- const locale = this.getLocale();
945
+ const locale = this.venusApi.getLocale();
1261
946
  const numberOptions = {
1262
947
  style: options?.style || "decimal",
1263
948
  minimumFractionDigits: options?.minimumFractionDigits || 0,
1264
949
  maximumFractionDigits: options?.maximumFractionDigits || 2,
1265
950
  ...options
1266
951
  };
1267
- console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
1268
952
  return value.toLocaleString(locale, numberOptions);
1269
953
  }
1270
954
  formatTime(timestamp, options) {
1271
- const locale = this.getLocale();
955
+ const locale = this.venusApi.getLocale();
1272
956
  const date = new Date(timestamp);
1273
957
  const dateTimeOptions = {
1274
958
  dateStyle: options.dateStyle || "medium",
@@ -1276,13 +960,9 @@ var MockTimeApi = class {
1276
960
  hour12: options.hour12 !== void 0 ? options.hour12 : true,
1277
961
  ...options
1278
962
  };
1279
- console.log(
1280
- `[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
1281
- );
1282
963
  return date.toLocaleString(locale, dateTimeOptions);
1283
964
  }
1284
965
  async getFutureTimeAsync(options) {
1285
- console.log("[Venus Mock] Getting future time with options:", options);
1286
966
  const timeInfo = await this.requestTimeAsync();
1287
967
  const serverTime = new Date(timeInfo.serverTime);
1288
968
  const result = new Date(serverTime);
@@ -1327,7 +1007,6 @@ var MockTimeApi = class {
1327
1007
  return result.getTime();
1328
1008
  }
1329
1009
  async requestTimeAsync() {
1330
- console.log("[Venus Mock] Requesting time");
1331
1010
  await createMockDelay(MOCK_DELAYS.short);
1332
1011
  const venusApi = this.venusApi;
1333
1012
  const mockOffset = venusApi._mock.serverTimeOffset || 2500;
@@ -1341,23 +1020,8 @@ var MockTimeApi = class {
1341
1020
  formattedTime: new Date(localTime).toISOString(),
1342
1021
  locale: venusApi._mock.user?.locale || "en-US"
1343
1022
  };
1344
- console.log("[Venus Mock] Time response:", {
1345
- serverTime: new Date(timeInfo.serverTime).toISOString(),
1346
- localTime: new Date(timeInfo.localTime).toISOString(),
1347
- timezoneOffset: timeInfo.timezoneOffset
1348
- });
1349
1023
  return timeInfo;
1350
1024
  }
1351
- getLocale() {
1352
- const venusApi = this.venusApi;
1353
- let locale = "en-US";
1354
- if (venusApi._mock.user && venusApi._mock.user.locale) {
1355
- locale = venusApi._mock.user.locale;
1356
- } else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
1357
- locale = venusApi._mock.environment.browserInfo.language;
1358
- }
1359
- return locale;
1360
- }
1361
1025
  };
1362
1026
 
1363
1027
  // src/time/index.ts
@@ -1392,7 +1056,7 @@ var MockAvatarApi = class {
1392
1056
  async deleteAvatar() {
1393
1057
  console.log(`[Venus Mock] Deleting avatar3d config`);
1394
1058
  const venusApi = this._venusApi;
1395
- const currentProfile = venusApi.getCurrentProfile();
1059
+ const currentProfile = venusApi.getProfile();
1396
1060
  const profileId = currentProfile?.id || "default_profile";
1397
1061
  localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
1398
1062
  console.log(
@@ -1407,7 +1071,7 @@ var MockAvatarApi = class {
1407
1071
  console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
1408
1072
  config = await this.selectAvatarConfig(avatar3dId, false);
1409
1073
  } else {
1410
- const currentProfile = venusApi.getCurrentProfile();
1074
+ const currentProfile = venusApi.getProfile();
1411
1075
  const profileId = currentProfile?.id || "default_profile";
1412
1076
  console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
1413
1077
  console.log(
@@ -1424,7 +1088,7 @@ var MockAvatarApi = class {
1424
1088
  async saveAvatar(config) {
1425
1089
  console.log(`[Venus Mock] Saving avatar3d config:`, config);
1426
1090
  const venusApi = this._venusApi;
1427
- const currentProfile = venusApi.getCurrentProfile();
1091
+ const currentProfile = venusApi.getProfile();
1428
1092
  const profileId = currentProfile?.id || "default_profile";
1429
1093
  localStorage.setItem(
1430
1094
  `venus-mock-avatar3d-${profileId}`,
@@ -2085,7 +1749,7 @@ var VenusAssetLoader = class {
2085
1749
  // Set the VenusAPI reference during initialization
2086
1750
  setVenusAPI(api) {
2087
1751
  this.venusAPI = api;
2088
- this.isWebView = !api.isWeb || !api.isWeb();
1752
+ this.isWebView = typeof window !== "undefined" && typeof window.ReactNativeWebView !== "undefined";
2089
1753
  }
2090
1754
  /**
2091
1755
  * Load any asset with automatic optimization
@@ -2206,14 +1870,11 @@ var VenusAssetLoader = class {
2206
1870
  }, 1e4);
2207
1871
  if (type === "image") {
2208
1872
  const img = new Image();
2209
- console.log(`\u{1F5BC}\uFE0F [Asset Verification] Verifying image: ${url}`);
2210
1873
  img.onload = () => {
2211
- console.log(`\u2705 [Asset Verification] Image verified successfully: ${url}`);
2212
1874
  clearTimeout(timeout);
2213
1875
  resolve();
2214
1876
  };
2215
1877
  img.onerror = (error) => {
2216
- console.log(`\u274C [Asset Verification] Image verification failed: ${url}`, error);
2217
1878
  clearTimeout(timeout);
2218
1879
  reject(new Error("Failed to load image"));
2219
1880
  };
@@ -2265,7 +1926,6 @@ var VenusAssetLoader = class {
2265
1926
  const CDN_BASE_URL = "https://venus-static-01293ak.web.app/";
2266
1927
  const cleanUrl = url.startsWith("/") ? url.slice(1) : url;
2267
1928
  const fullUrl = CDN_BASE_URL + cleanUrl;
2268
- console.log(`\u{1F310} [Asset Loader] Force remote CDN: ${url} -> ${fullUrl}`);
2269
1929
  return fullUrl;
2270
1930
  }
2271
1931
  if (this.venusAPI && this.venusAPI.isMock && this.venusAPI.isMock()) {
@@ -3976,47 +3636,105 @@ function initializeIap(venusApiInstance, host) {
3976
3636
  venusApiInstance.iap = host.iap;
3977
3637
  }
3978
3638
 
3639
+ // src/leaderboard/utils.ts
3640
+ var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
3641
+ async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
3642
+ const payload = `score:${score}|duration:${duration}|token:${token}`;
3643
+ const fullPayload = `${payload}|nonce:${sealingNonce}`;
3644
+ const encoder = new TextEncoder();
3645
+ const keyData = encoder.encode(sealingSecret);
3646
+ const messageData = encoder.encode(fullPayload);
3647
+ const cryptoKey = await crypto.subtle.importKey(
3648
+ "raw",
3649
+ keyData,
3650
+ { name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
3651
+ false,
3652
+ ["sign"]
3653
+ );
3654
+ const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
3655
+ return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
3656
+ }
3657
+
3979
3658
  // src/leaderboard/RpcLeaderboardApi.ts
3980
3659
  var RpcLeaderboardApi = class {
3981
3660
  constructor(rpcClient) {
3982
3661
  __publicField(this, "rpcClient");
3662
+ /** Cache of score tokens for automatic hash computation */
3663
+ __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3983
3664
  this.rpcClient = rpcClient;
3984
3665
  }
3985
- startRun(mode) {
3986
- return this.rpcClient.call(
3987
- "H5_LEADERBOARD_START_RUN" /* H5_LEADERBOARD_START_RUN */,
3666
+ /**
3667
+ * Create a score token for submitting a score.
3668
+ * Token is cached for automatic hash computation if score sealing is enabled.
3669
+ *
3670
+ * @param mode - Optional game mode
3671
+ * @returns Score token with sealing data if enabled
3672
+ */
3673
+ async createScoreToken(mode) {
3674
+ const token = await this.rpcClient.call(
3675
+ "H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
3988
3676
  mode ? { mode } : {}
3989
3677
  );
3678
+ this.tokenCache.set(token.token, token);
3679
+ return token;
3990
3680
  }
3991
- submitScore(sessionId, score, durationSec, options) {
3681
+ /**
3682
+ * Submit a score to the leaderboard.
3683
+ * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3684
+ *
3685
+ * @param params - Score submission parameters
3686
+ * @returns Submission result with acceptance status and rank
3687
+ * @throws Error if token not found in cache
3688
+ */
3689
+ async submitScore(params) {
3690
+ let hash;
3691
+ if (params.token) {
3692
+ const cachedToken = this.tokenCache.get(params.token);
3693
+ if (!cachedToken) {
3694
+ throw new Error(
3695
+ "Invalid token: not found in cache. Did you call createScoreToken() first?"
3696
+ );
3697
+ }
3698
+ if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3699
+ hash = await computeScoreHash(
3700
+ params.score,
3701
+ params.duration,
3702
+ params.token,
3703
+ cachedToken.sealingNonce,
3704
+ cachedToken.sealingSecret
3705
+ );
3706
+ }
3707
+ this.tokenCache.delete(params.token);
3708
+ }
3992
3709
  return this.rpcClient.call(
3993
3710
  "H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
3994
3711
  {
3995
- sessionId,
3996
- score,
3997
- durationSec,
3998
- mode: options?.mode,
3999
- telemetry: options?.telemetry,
4000
- metadata: options?.metadata,
4001
- hash: options?.hash
3712
+ token: params.token,
3713
+ score: params.score,
3714
+ duration: params.duration,
3715
+ mode: params.mode,
3716
+ telemetry: params.telemetry,
3717
+ metadata: params.metadata,
3718
+ hash
3719
+ // undefined if no sealing, computed if sealing enabled
4002
3720
  }
4003
3721
  );
4004
3722
  }
4005
- getLeaderboard(options) {
3723
+ getPagedScores(options) {
4006
3724
  return this.rpcClient.call(
4007
- "H5_LEADERBOARD_GET" /* H5_LEADERBOARD_GET */,
3725
+ "H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
4008
3726
  options ?? {}
4009
3727
  );
4010
3728
  }
4011
- getPlayerStats(options) {
3729
+ getMyRank(options) {
4012
3730
  return this.rpcClient.call(
4013
- "H5_LEADERBOARD_GET_PLAYER_STATS" /* H5_LEADERBOARD_GET_PLAYER_STATS */,
3731
+ "H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
4014
3732
  options ?? {}
4015
3733
  );
4016
3734
  }
4017
- getLeaderboardHighlight(options) {
3735
+ getPodiumScores(options) {
4018
3736
  return this.rpcClient.call(
4019
- "H5_LEADERBOARD_GET_HIGHLIGHT" /* H5_LEADERBOARD_GET_HIGHLIGHT */,
3737
+ "H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
4020
3738
  options ?? {}
4021
3739
  );
4022
3740
  }
@@ -4025,17 +3743,31 @@ var RpcLeaderboardApi = class {
4025
3743
  // src/leaderboard/MockLeaderboardApi.ts
4026
3744
  var MockLeaderboardApi = class {
4027
3745
  constructor(options) {
4028
- __publicField(this, "sessions", /* @__PURE__ */ new Map());
3746
+ __publicField(this, "tokens", /* @__PURE__ */ new Map());
3747
+ /** Cache of score tokens for automatic hash computation */
3748
+ __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
4029
3749
  __publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
4030
- __publicField(this, "sessionCounter", 0);
4031
- __publicField(this, "requiresHash", false);
4032
- if (options?.requiresHash) {
4033
- this.requiresHash = true;
3750
+ __publicField(this, "tokenCounter", 0);
3751
+ __publicField(this, "enableScoreSealing", false);
3752
+ __publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
3753
+ if (options?.enableScoreSealing) {
3754
+ this.enableScoreSealing = true;
3755
+ }
3756
+ if (options?.scoreSealingSecret) {
3757
+ this.scoreSealingSecret = options.scoreSealingSecret;
4034
3758
  }
4035
3759
  }
3760
+ /**
3761
+ * Configure mock leaderboard settings
3762
+ *
3763
+ * @param options - Configuration options
3764
+ */
4036
3765
  configure(options) {
4037
- if (typeof options.requiresHash === "boolean") {
4038
- this.requiresHash = options.requiresHash;
3766
+ if (typeof options.enableScoreSealing === "boolean") {
3767
+ this.enableScoreSealing = options.enableScoreSealing;
3768
+ }
3769
+ if (options.scoreSealingSecret) {
3770
+ this.scoreSealingSecret = options.scoreSealingSecret;
4039
3771
  }
4040
3772
  }
4041
3773
  generateNonce() {
@@ -4052,83 +3784,149 @@ var MockLeaderboardApi = class {
4052
3784
  }
4053
3785
  return this.entriesByMode.get(key);
4054
3786
  }
4055
- async startRun(mode) {
4056
- const sessionId = `mock_session_${++this.sessionCounter}`;
3787
+ /**
3788
+ * Create a mock score token for testing.
3789
+ * Token is cached for automatic hash computation if score sealing is enabled.
3790
+ *
3791
+ * @param mode - Optional game mode
3792
+ * @returns Score token with sealing data if enabled
3793
+ */
3794
+ async createScoreToken(mode) {
3795
+ const token = `mock_token_${++this.tokenCounter}`;
4057
3796
  const startTime = Date.now();
4058
3797
  const expiresAt = startTime + 36e5;
4059
3798
  const resolvedMode = mode || "default";
4060
- const hashNonce = this.requiresHash ? this.generateNonce() : null;
4061
- this.sessions.set(sessionId, {
4062
- id: sessionId,
3799
+ const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
3800
+ const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
3801
+ this.tokens.set(token, {
3802
+ id: token,
4063
3803
  expiresAt,
4064
3804
  mode: resolvedMode,
4065
- hashNonce,
3805
+ sealingNonce,
4066
3806
  used: false
4067
3807
  });
4068
- return {
4069
- sessionId,
3808
+ const result = {
3809
+ token,
4070
3810
  startTime,
4071
3811
  expiresAt,
4072
- hashNonce,
3812
+ sealingNonce,
3813
+ sealingSecret,
4073
3814
  mode: resolvedMode
4074
3815
  };
3816
+ this.tokenCache.set(token, result);
3817
+ return result;
4075
3818
  }
4076
- async submitScore(sessionId, score, durationSec, options) {
4077
- const session = this.sessions.get(sessionId);
4078
- if (!session) {
4079
- throw new Error("Invalid leaderboard session");
3819
+ /**
3820
+ * Submit a mock score to the leaderboard.
3821
+ * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3822
+ *
3823
+ * @param params - Score submission parameters
3824
+ * @returns Submission result with acceptance status and rank
3825
+ * @throws Error if token not found in cache or validation fails
3826
+ */
3827
+ async submitScore(params) {
3828
+ let hash;
3829
+ if (params.token) {
3830
+ const cachedToken = this.tokenCache.get(params.token);
3831
+ if (!cachedToken) {
3832
+ throw new Error(
3833
+ "Invalid token: not found in cache. Did you call createScoreToken() first?"
3834
+ );
3835
+ }
3836
+ if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3837
+ hash = await computeScoreHash(
3838
+ params.score,
3839
+ params.duration,
3840
+ params.token,
3841
+ cachedToken.sealingNonce,
3842
+ cachedToken.sealingSecret
3843
+ );
3844
+ }
3845
+ }
3846
+ if (!params.token) {
3847
+ const mode = params.mode || "default";
3848
+ const submittedAt2 = Date.now();
3849
+ const entry2 = {
3850
+ profileId: `mock_profile`,
3851
+ username: "Mock Player",
3852
+ avatarUrl: null,
3853
+ score: params.score,
3854
+ duration: params.duration,
3855
+ submittedAt: submittedAt2,
3856
+ token: "simple-mode",
3857
+ rank: null,
3858
+ zScore: null,
3859
+ isAnomaly: false,
3860
+ trustScore: 50,
3861
+ metadata: params.metadata ?? null,
3862
+ isSeed: false
3863
+ };
3864
+ const modeEntries2 = this.getEntriesForMode(mode);
3865
+ modeEntries2.push(entry2);
3866
+ modeEntries2.sort((a, b) => {
3867
+ if (b.score !== a.score) return b.score - a.score;
3868
+ return a.submittedAt - b.submittedAt;
3869
+ });
3870
+ modeEntries2.forEach((e, index) => {
3871
+ modeEntries2[index] = { ...e, rank: index + 1 };
3872
+ });
3873
+ const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
3874
+ return {
3875
+ accepted: true,
3876
+ rank: inserted2?.rank ?? null
3877
+ };
4080
3878
  }
4081
- if (session.expiresAt < Date.now()) {
4082
- throw new Error("Invalid or expired leaderboard session");
3879
+ const scoreToken = this.tokens.get(params.token);
3880
+ if (!scoreToken) {
3881
+ throw new Error("Invalid score token");
4083
3882
  }
4084
- if (session.used) {
4085
- throw new Error("Leaderboard session already used");
3883
+ if (scoreToken.expiresAt < Date.now()) {
3884
+ throw new Error("Invalid or expired score token");
4086
3885
  }
4087
- if (options?.mode && options.mode !== session.mode) {
4088
- throw new Error("Submission mode does not match session mode");
3886
+ if (scoreToken.used) {
3887
+ throw new Error("Score token already used");
4089
3888
  }
4090
- if (session.hashNonce && !options?.hash) {
4091
- throw new Error("Score hash is required for sealed leaderboard submissions");
3889
+ if (params.mode && params.mode !== scoreToken.mode) {
3890
+ throw new Error("Submission mode does not match token mode");
3891
+ }
3892
+ if (scoreToken.sealingNonce && !hash) {
3893
+ throw new Error("Score hash required when score sealing is enabled");
4092
3894
  }
4093
3895
  const submittedAt = Date.now();
4094
3896
  const entry = {
4095
3897
  profileId: `mock_profile`,
4096
3898
  username: "Mock Player",
4097
3899
  avatarUrl: null,
4098
- score,
4099
- durationSec,
3900
+ score: params.score,
3901
+ duration: params.duration,
4100
3902
  submittedAt,
4101
- sessionId,
3903
+ token: params.token,
4102
3904
  rank: null,
4103
3905
  zScore: null,
4104
3906
  isAnomaly: false,
4105
3907
  trustScore: 50,
4106
- metadata: options?.metadata ?? null,
3908
+ metadata: params.metadata ?? null,
4107
3909
  isSeed: false
4108
3910
  };
4109
- const modeEntries = this.getEntriesForMode(session.mode);
3911
+ const modeEntries = this.getEntriesForMode(scoreToken.mode);
4110
3912
  modeEntries.push(entry);
4111
3913
  modeEntries.sort((a, b) => {
4112
- if (b.score !== a.score) {
4113
- return b.score - a.score;
4114
- }
3914
+ if (b.score !== a.score) return b.score - a.score;
4115
3915
  return a.submittedAt - b.submittedAt;
4116
3916
  });
4117
3917
  modeEntries.forEach((e, index) => {
4118
- modeEntries[index] = {
4119
- ...e,
4120
- rank: index + 1
4121
- };
3918
+ modeEntries[index] = { ...e, rank: index + 1 };
4122
3919
  });
4123
- session.used = true;
4124
- session.hashNonce = null;
4125
- const inserted = modeEntries.find((e) => e.sessionId === sessionId && e.submittedAt === submittedAt);
3920
+ scoreToken.used = true;
3921
+ scoreToken.sealingNonce = null;
3922
+ this.tokenCache.delete(params.token);
3923
+ const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
4126
3924
  return {
4127
3925
  accepted: true,
4128
3926
  rank: inserted?.rank ?? null
4129
3927
  };
4130
3928
  }
4131
- async getLeaderboard(options) {
3929
+ async getPagedScores(options) {
4132
3930
  const limit = options?.limit ?? 10;
4133
3931
  const mode = options?.mode ?? "default";
4134
3932
  const modeEntries = [...this.getEntriesForMode(mode)];
@@ -4144,7 +3942,7 @@ var MockLeaderboardApi = class {
4144
3942
  periodInstance: options?.period ?? "alltime"
4145
3943
  };
4146
3944
  }
4147
- async getPlayerStats(_options) {
3945
+ async getMyRank(_options) {
4148
3946
  const mode = _options?.mode ?? "default";
4149
3947
  const modeEntries = this.getEntriesForMode(mode);
4150
3948
  const playerEntry = modeEntries[0] ?? null;
@@ -4157,7 +3955,7 @@ var MockLeaderboardApi = class {
4157
3955
  periodInstance: _options?.period ?? "alltime"
4158
3956
  };
4159
3957
  }
4160
- async getLeaderboardHighlight(options) {
3958
+ async getPodiumScores(options) {
4161
3959
  const mode = options?.mode ?? "default";
4162
3960
  const modeEntries = [...this.getEntriesForMode(mode)];
4163
3961
  const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
@@ -4210,16 +4008,20 @@ function initializeLeaderboard(venusApiInstance, host) {
4210
4008
 
4211
4009
  // src/profile/HostProfileApi.ts
4212
4010
  var HostProfileApi = class {
4011
+ constructor(venusApi) {
4012
+ __publicField(this, "venusApi");
4013
+ this.venusApi = venusApi;
4014
+ }
4213
4015
  getCurrentProfile() {
4214
- const profile = window.venus?.profile;
4016
+ const profile = this.venusApi._profileData;
4215
4017
  if (!profile) {
4216
4018
  throw new Error(
4217
- "[Venus SDK] Host profile handshake did not complete. Await VenusAPI.initializeAsync() so INIT_SDK can deliver the profile before calling profile APIs."
4019
+ "[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
4218
4020
  );
4219
4021
  }
4220
4022
  if (!profile.id || !profile.username) {
4221
4023
  throw new Error(
4222
- "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply real credentials before rooms APIs are used."
4024
+ "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
4223
4025
  );
4224
4026
  }
4225
4027
  return {
@@ -4233,6 +4035,10 @@ var HostProfileApi = class {
4233
4035
 
4234
4036
  // src/profile/MockProfileApi.ts
4235
4037
  var MockProfileApi = class {
4038
+ constructor(venusApi) {
4039
+ __publicField(this, "venusApi");
4040
+ this.venusApi = venusApi;
4041
+ }
4236
4042
  getCurrentProfile() {
4237
4043
  return {
4238
4044
  id: "mock_profile_123",
@@ -4245,12 +4051,224 @@ var MockProfileApi = class {
4245
4051
 
4246
4052
  // src/profile/index.ts
4247
4053
  function initializeProfile(venusApi, host) {
4054
+ venusApi.getProfile = () => {
4055
+ return host.profile.getCurrentProfile();
4056
+ };
4248
4057
  venusApi.getCurrentProfile = () => {
4058
+ console.warn(
4059
+ "[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
4060
+ );
4249
4061
  return host.profile.getCurrentProfile();
4250
4062
  };
4251
4063
  }
4252
4064
 
4253
- // src/cdn/HostCdnApi.ts
4065
+ // src/system/HostSystemApi.ts
4066
+ var HostSystemApi = class {
4067
+ constructor(deviceApi, environmentApi, venusApi) {
4068
+ __publicField(this, "deviceApi");
4069
+ __publicField(this, "environmentApi");
4070
+ __publicField(this, "venusApi");
4071
+ this.deviceApi = deviceApi;
4072
+ this.environmentApi = environmentApi;
4073
+ this.venusApi = venusApi;
4074
+ }
4075
+ getDevice() {
4076
+ return this.deviceApi.getDevice();
4077
+ }
4078
+ getEnvironment() {
4079
+ return this.environmentApi.getEnvironment();
4080
+ }
4081
+ getSafeArea() {
4082
+ const safeArea = this.venusApi._safeAreaData;
4083
+ if (!safeArea) {
4084
+ throw new Error(
4085
+ "[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
4086
+ );
4087
+ }
4088
+ return { ...safeArea };
4089
+ }
4090
+ isMobile() {
4091
+ const environment = this.environmentApi.getEnvironment();
4092
+ if (environment.platform === "ios" || environment.platform === "android") {
4093
+ return true;
4094
+ }
4095
+ if (environment.browserInfo) {
4096
+ return environment.browserInfo.isMobile;
4097
+ }
4098
+ return true;
4099
+ }
4100
+ isWeb() {
4101
+ const environment = this.environmentApi.getEnvironment();
4102
+ if (environment.platform === "web") {
4103
+ return true;
4104
+ }
4105
+ if (environment.browserInfo && !environment.browserInfo.isMobile) {
4106
+ return true;
4107
+ }
4108
+ return false;
4109
+ }
4110
+ };
4111
+
4112
+ // src/system/MockSystemApi.ts
4113
+ var MockSystemApi = class {
4114
+ constructor(deviceApi, environmentApi, venusApi) {
4115
+ __publicField(this, "deviceApi");
4116
+ __publicField(this, "environmentApi");
4117
+ __publicField(this, "venusApi");
4118
+ this.deviceApi = deviceApi;
4119
+ this.environmentApi = environmentApi;
4120
+ this.venusApi = venusApi;
4121
+ }
4122
+ getDevice() {
4123
+ return this.deviceApi.getDevice();
4124
+ }
4125
+ getEnvironment() {
4126
+ return this.environmentApi.getEnvironment();
4127
+ }
4128
+ getSafeArea() {
4129
+ const safeArea = this.venusApi._safeAreaData;
4130
+ if (!safeArea) {
4131
+ return {
4132
+ top: 0,
4133
+ right: 0,
4134
+ bottom: 34,
4135
+ left: 0
4136
+ };
4137
+ }
4138
+ return { ...safeArea };
4139
+ }
4140
+ isMobile() {
4141
+ const environment = this.environmentApi.getEnvironment();
4142
+ if (environment.platform === "ios" || environment.platform === "android") {
4143
+ return true;
4144
+ }
4145
+ if (environment.browserInfo) {
4146
+ return environment.browserInfo.isMobile;
4147
+ }
4148
+ return true;
4149
+ }
4150
+ isWeb() {
4151
+ const environment = this.environmentApi.getEnvironment();
4152
+ if (environment.platform === "web") {
4153
+ return true;
4154
+ }
4155
+ if (environment.browserInfo && !environment.browserInfo.isMobile) {
4156
+ return true;
4157
+ }
4158
+ return false;
4159
+ }
4160
+ };
4161
+
4162
+ // src/system/index.ts
4163
+ function initializeSystem(venusApi, host) {
4164
+ venusApi.system = host.system;
4165
+ venusApi.isMobile = () => {
4166
+ console.warn(
4167
+ "[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
4168
+ );
4169
+ return host.system.isMobile();
4170
+ };
4171
+ venusApi.isWeb = () => {
4172
+ console.warn(
4173
+ "[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
4174
+ );
4175
+ return host.system.isWeb();
4176
+ };
4177
+ }
4178
+
4179
+ // src/device/HostDeviceApi.ts
4180
+ var HostDeviceApi = class {
4181
+ constructor(venusApi) {
4182
+ __publicField(this, "venusApi");
4183
+ this.venusApi = venusApi;
4184
+ }
4185
+ getDevice() {
4186
+ const device = this.venusApi._deviceData;
4187
+ if (!device) {
4188
+ throw new Error(
4189
+ "[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
4190
+ );
4191
+ }
4192
+ return device;
4193
+ }
4194
+ };
4195
+
4196
+ // src/device/MockDeviceApi.ts
4197
+ var MockDeviceApi = class {
4198
+ constructor(venusApi) {
4199
+ __publicField(this, "venusApi");
4200
+ this.venusApi = venusApi;
4201
+ }
4202
+ getDevice() {
4203
+ const width = typeof window !== "undefined" ? window.innerWidth : 400;
4204
+ const height = typeof window !== "undefined" ? window.innerHeight : 800;
4205
+ return {
4206
+ screenSize: { width, height },
4207
+ viewportSize: {
4208
+ width: width - 20,
4209
+ // account for safe area
4210
+ height: height - 20
4211
+ },
4212
+ orientation: width > height ? "landscape" : "portrait",
4213
+ pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
4214
+ fontScale: 1,
4215
+ deviceType: width > 768 ? "tablet" : "phone",
4216
+ hapticsEnabled: false,
4217
+ haptics: { supported: false, enabled: false }
4218
+ };
4219
+ }
4220
+ };
4221
+
4222
+ // src/environment/HostEnvironmentApi.ts
4223
+ var HostEnvironmentApi = class {
4224
+ constructor(venusApi) {
4225
+ __publicField(this, "venusApi");
4226
+ this.venusApi = venusApi;
4227
+ }
4228
+ getEnvironment() {
4229
+ const environment = this.venusApi._environmentData;
4230
+ if (!environment) {
4231
+ throw new Error(
4232
+ "[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
4233
+ );
4234
+ }
4235
+ return environment;
4236
+ }
4237
+ };
4238
+
4239
+ // src/environment/MockEnvironmentApi.ts
4240
+ var MockEnvironmentApi = class {
4241
+ constructor(venusApi) {
4242
+ __publicField(this, "venusApi");
4243
+ this.venusApi = venusApi;
4244
+ }
4245
+ getEnvironment() {
4246
+ const getBrowser = () => {
4247
+ if (typeof navigator === "undefined") return "unknown";
4248
+ const userAgent = navigator.userAgent;
4249
+ if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
4250
+ if (/firefox|fxios/i.test(userAgent)) return "firefox";
4251
+ if (/safari/i.test(userAgent)) return "safari";
4252
+ if (/edg/i.test(userAgent)) return "edge";
4253
+ if (/opera|opr/i.test(userAgent)) return "opera";
4254
+ return "unknown";
4255
+ };
4256
+ return {
4257
+ isDevelopment: true,
4258
+ platform: "web",
4259
+ platformVersion: "mock-1.0",
4260
+ browserInfo: {
4261
+ browser: getBrowser(),
4262
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
4263
+ isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
4264
+ isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
4265
+ language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
4266
+ }
4267
+ };
4268
+ }
4269
+ };
4270
+
4271
+ // src/cdn/HostCdnApi.ts
4254
4272
  var HostCdnApi = class {
4255
4273
  constructor(baseUrl) {
4256
4274
  __publicField(this, "baseUrl");
@@ -4307,7 +4325,8 @@ var HostCdnApi = class {
4307
4325
  return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
4308
4326
  });
4309
4327
  const encodedSubPath = encodedParts.join("/");
4310
- const fullUrl = this.baseUrl + "/" + encodedSubPath;
4328
+ const cacheBust = Date.now();
4329
+ const fullUrl = this.baseUrl + "/" + encodedSubPath + `?cacheBust=${cacheBust}`;
4311
4330
  return fullUrl;
4312
4331
  }
4313
4332
  resolveAvatarAssetUrl(subPath) {
@@ -4322,9 +4341,15 @@ var HostCdnApi = class {
4322
4341
 
4323
4342
  // src/cdn/MockCdnApi.ts
4324
4343
  var MockCdnApi = class {
4325
- constructor() {
4326
- __publicField(this, "baseUrl");
4327
- this.baseUrl = "https://venus-static-01293ak.web.app/";
4344
+ constructor(venusApi) {
4345
+ __publicField(this, "venusApi");
4346
+ this.venusApi = venusApi;
4347
+ }
4348
+ get baseUrl() {
4349
+ return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
4350
+ }
4351
+ get forceRemoteCdn() {
4352
+ return this.venusApi._mock?.cdnForceRemote ?? false;
4328
4353
  }
4329
4354
  async fetchBlob(path, options) {
4330
4355
  const controller = new AbortController();
@@ -4361,6 +4386,10 @@ var MockCdnApi = class {
4361
4386
  return subPath;
4362
4387
  }
4363
4388
  const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
4389
+ const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
4390
+ if (isLocalhost && !this.forceRemoteCdn) {
4391
+ return `/${cleanSubPath}`;
4392
+ }
4364
4393
  const pathParts = cleanSubPath.split("/");
4365
4394
  const encodedParts = pathParts.map((part, index) => {
4366
4395
  return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
@@ -4482,96 +4511,6 @@ function initializeCdn(venusApi, host) {
4482
4511
  venusApi.cdn = host.cdn;
4483
4512
  }
4484
4513
 
4485
- // src/post/MockPostApi.ts
4486
- init_core();
4487
- var MockPostApi = class {
4488
- constructor(venusApi) {
4489
- __publicField(this, "venusApi");
4490
- this.venusApi = venusApi;
4491
- }
4492
- async getPostInfo() {
4493
- const venusApi = this.venusApi;
4494
- await createMockDelay(MOCK_DELAYS.short);
4495
- return venusApi._mock.currentPostInteractions;
4496
- }
4497
- async openCommentsAsync() {
4498
- await createMockDelay(MOCK_DELAYS.short);
4499
- return {
4500
- opened: true,
4501
- commentsCount: 0
4502
- };
4503
- }
4504
- async toggleFollowAsync() {
4505
- const venusApi = this.venusApi;
4506
- console.log("[Venus Mock] *Toggling follow status");
4507
- await createMockDelay(MOCK_DELAYS.short);
4508
- venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
4509
- const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
4510
- return {
4511
- isFollowing,
4512
- action: isFollowing ? "followed" : "unfollowed"
4513
- };
4514
- }
4515
- async toggleLikeAsync() {
4516
- const venusApi = this.venusApi;
4517
- await createMockDelay(MOCK_DELAYS.short);
4518
- venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
4519
- const isLiked = venusApi._mock.currentPostInteractions.isLiked;
4520
- if (isLiked) {
4521
- venusApi._mock.currentPostInteractions.likesCount++;
4522
- } else {
4523
- venusApi._mock.currentPostInteractions.likesCount = Math.max(
4524
- 0,
4525
- venusApi._mock.currentPostInteractions.likesCount - 1
4526
- );
4527
- }
4528
- return {
4529
- isLiked,
4530
- likesCount: venusApi._mock.currentPostInteractions.likesCount,
4531
- action: isLiked ? "liked" : "unliked"
4532
- };
4533
- }
4534
- };
4535
-
4536
- // src/post/RpcPostApi.ts
4537
- var RpcPostApi = class {
4538
- constructor(rpcClient) {
4539
- __publicField(this, "rpcClient");
4540
- this.rpcClient = rpcClient;
4541
- }
4542
- getPostInfo() {
4543
- return this.rpcClient.call("H5_GET_POST_INTERACTIONS" /* GET_POST_INTERACTIONS */, {});
4544
- }
4545
- openCommentsAsync() {
4546
- return this.rpcClient.call("H5_OPEN_COMMENTS" /* OPEN_COMMENTS */, {});
4547
- }
4548
- toggleFollowAsync() {
4549
- return this.rpcClient.call(
4550
- "H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
4551
- {}
4552
- );
4553
- }
4554
- toggleLikeAsync() {
4555
- return this.rpcClient.call("H5_TOGGLE_LIKE" /* TOGGLE_LIKE */, {});
4556
- }
4557
- };
4558
-
4559
- // src/post/index.ts
4560
- function initializePost(venusApi, host) {
4561
- venusApi.getPostInteractionsAsync = () => {
4562
- return host.post.getPostInfo();
4563
- };
4564
- venusApi.toggleFollowAsync = () => {
4565
- return host.post.toggleFollowAsync();
4566
- };
4567
- venusApi.toggleLikeAsync = () => {
4568
- return host.post.toggleLikeAsync();
4569
- };
4570
- venusApi.openCommentsAsync = async () => {
4571
- await host.post.openCommentsAsync();
4572
- };
4573
- }
4574
-
4575
4514
  // src/haptics/RpcHapticsApi.ts
4576
4515
  var RpcHapticsApi = class {
4577
4516
  constructor(rpcClient) {
@@ -4762,871 +4701,426 @@ function initializeLifecycleApi(venusApi, host) {
4762
4701
  venusApi.lifecycles = host.lifecycle;
4763
4702
  }
4764
4703
 
4765
- // src/simulation/utils.ts
4766
- function sumContributions(contributions) {
4767
- const totals = {};
4768
- for (const profileId in contributions) {
4769
- for (const entityId in contributions[profileId]) {
4770
- const amount = contributions[profileId][entityId] || 0;
4771
- totals[entityId] = (totals[entityId] || 0) + amount;
4772
- }
4704
+ // src/rooms/VenusRoom.ts
4705
+ var VenusRoom = class {
4706
+ constructor(roomData) {
4707
+ __publicField(this, "id");
4708
+ __publicField(this, "name");
4709
+ __publicField(this, "players");
4710
+ __publicField(this, "maxPlayers");
4711
+ __publicField(this, "gameType");
4712
+ __publicField(this, "appId");
4713
+ __publicField(this, "type");
4714
+ __publicField(this, "createdBy");
4715
+ __publicField(this, "createdAt");
4716
+ __publicField(this, "updatedAt");
4717
+ __publicField(this, "isPrivate");
4718
+ __publicField(this, "status");
4719
+ __publicField(this, "customMetadata");
4720
+ __publicField(this, "admins");
4721
+ __publicField(this, "roomCode");
4722
+ __publicField(this, "description");
4723
+ __publicField(this, "data");
4724
+ __publicField(this, "version");
4725
+ this.id = roomData.id;
4726
+ this.name = roomData.name;
4727
+ this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
4728
+ this.maxPlayers = roomData.maxPlayers;
4729
+ this.gameType = roomData.gameType;
4730
+ this.appId = roomData.appId;
4731
+ this.type = roomData.type;
4732
+ this.createdBy = roomData.createdBy;
4733
+ this.createdAt = roomData.createdAt;
4734
+ this.updatedAt = roomData.updatedAt;
4735
+ this.isPrivate = roomData.isPrivate;
4736
+ this.status = roomData.status;
4737
+ this.customMetadata = roomData.customMetadata || {};
4738
+ this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
4739
+ this.roomCode = roomData.roomCode;
4740
+ this.description = roomData.description;
4741
+ this.data = roomData.data || {};
4742
+ this.version = roomData.version;
4773
4743
  }
4774
- return totals;
4744
+ };
4745
+
4746
+ // src/rooms/setupRoomNotifications.ts
4747
+ function invokeCallbacks(callbacks, event, context) {
4748
+ callbacks.forEach((callback) => {
4749
+ try {
4750
+ callback(event);
4751
+ } catch (error) {
4752
+ console.error(`[Venus SDK] Error in ${context} callback:`, error);
4753
+ throw error;
4754
+ }
4755
+ });
4756
+ }
4757
+ function setupRoomNotifications(transport, getSubscriptions) {
4758
+ return transport.onVenusMessage((message) => {
4759
+ const subscriptions = getSubscriptions();
4760
+ if (!subscriptions) {
4761
+ return;
4762
+ }
4763
+ if (message.type === "H5_ROOM_DATA_UPDATED") {
4764
+ const messageData = message.data;
4765
+ const { roomId, roomData } = messageData;
4766
+ if (!roomId) return;
4767
+ const callbacks = subscriptions.data[roomId] || [];
4768
+ const event = {
4769
+ type: "H5_ROOM_DATA_UPDATED",
4770
+ roomId,
4771
+ roomData,
4772
+ timestamp: messageData.timestamp
4773
+ };
4774
+ invokeCallbacks(callbacks, event, "room data");
4775
+ }
4776
+ if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
4777
+ const messageData = message.data;
4778
+ const { roomId } = messageData;
4779
+ if (!roomId) return;
4780
+ const callbacks = subscriptions.messages[roomId] || [];
4781
+ const event = {
4782
+ type: message.type,
4783
+ roomId,
4784
+ message: messageData.message,
4785
+ timestamp: messageData.timestamp
4786
+ };
4787
+ invokeCallbacks(callbacks, event, "room message");
4788
+ }
4789
+ if (message.type === "app:h5:proposedMoveValidationUpdated") {
4790
+ const messageData = message.data;
4791
+ const { roomId } = messageData;
4792
+ if (!roomId) return;
4793
+ const callbacks = subscriptions.gameEvents[roomId] || [];
4794
+ const event = {
4795
+ type: "app:h5:proposedMoveValidationUpdated",
4796
+ roomId,
4797
+ proposedMoveData: messageData.proposedMoveData,
4798
+ proposedMoveId: messageData.proposedMoveId,
4799
+ changeType: messageData.changeType,
4800
+ timestamp: messageData.timestamp
4801
+ };
4802
+ invokeCallbacks(callbacks, event, "game event");
4803
+ }
4804
+ });
4775
4805
  }
4776
4806
 
4777
- // src/simulation/RpcSimulationApi.ts
4778
- var RpcSimulationApi = class {
4807
+ // src/rooms/RpcRoomsApi.ts
4808
+ var RpcRoomsApi = class {
4779
4809
  constructor(rpcClient) {
4780
4810
  __publicField(this, "rpcClient");
4781
- __publicField(this, "_simulationConfig", null);
4811
+ __publicField(this, "subscriptions");
4782
4812
  this.rpcClient = rpcClient;
4813
+ this.subscriptions = {
4814
+ data: {},
4815
+ messages: {},
4816
+ gameEvents: {}
4817
+ };
4783
4818
  }
4784
- async validateSlotAssignmentAsync(containerId, slotId, itemId) {
4785
- return this.rpcClient.call(
4786
- "H5_SIMULATION_VALIDATE_ASSIGNMENT" /* H5_SIMULATION_VALIDATE_ASSIGNMENT */,
4819
+ /**
4820
+ * Get the subscription state for external access (used by setupRoomNotifications)
4821
+ */
4822
+ getSubscriptions() {
4823
+ return this.subscriptions;
4824
+ }
4825
+ /**
4826
+ * Set up room notification routing from the transport
4827
+ */
4828
+ setupNotifications(transport) {
4829
+ setupRoomNotifications(transport, () => this.getSubscriptions());
4830
+ }
4831
+ async createRoomAsync(options) {
4832
+ const response = await this.rpcClient.call(
4833
+ "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
4787
4834
  {
4788
- containerId,
4789
- slotId,
4790
- itemId
4835
+ options
4791
4836
  }
4792
4837
  );
4838
+ if (response.success === false) {
4839
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
4840
+ throw new Error(errorMessage);
4841
+ }
4842
+ const room = new VenusRoom(response.roomData);
4843
+ return room;
4793
4844
  }
4794
- sumContributions(contributions) {
4795
- return sumContributions(contributions);
4796
- }
4797
- executeBatchOperationsAsync(operations, validateOnly) {
4798
- return this.rpcClient.call("H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */, {
4799
- operations,
4800
- validateOnly
4801
- });
4802
- }
4803
- async getAvailableItemsAsync(containerId, slotId) {
4845
+ async joinOrCreateRoomAsync(options) {
4804
4846
  const response = await this.rpcClient.call(
4805
- "H5_SIMULATION_GET_AVAILABLE_ITEMS" /* H5_SIMULATION_GET_AVAILABLE_ITEMS */,
4847
+ "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
4806
4848
  {
4807
- containerId,
4808
- slotId
4849
+ options
4809
4850
  }
4810
4851
  );
4811
- return response.availableItems || [];
4852
+ if (response.success === false) {
4853
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
4854
+ throw new Error(errorMessage);
4855
+ }
4856
+ const room = new VenusRoom(response.value.roomData);
4857
+ return {
4858
+ action: response.value.action,
4859
+ room,
4860
+ playersJoined: response.value.playersJoined
4861
+ };
4812
4862
  }
4813
- calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
4814
- return this.rpcClient.call(
4815
- "H5_SIMULATION_CALCULATE_POWER_PREVIEW" /* H5_SIMULATION_CALCULATE_POWER_PREVIEW */,
4863
+ async joinRoomByCodeAsync(roomCode) {
4864
+ const response = await this.rpcClient.call(
4865
+ "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
4816
4866
  {
4817
- containerId,
4818
- slotId,
4819
- candidateItemId
4867
+ roomCode
4820
4868
  }
4821
4869
  );
4870
+ if (response?.success === false) {
4871
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
4872
+ throw new Error(errorMessage);
4873
+ }
4874
+ const room = new VenusRoom(response.roomData);
4875
+ return room;
4822
4876
  }
4823
- assignItemToSlotAsync(containerId, slotId, itemId) {
4824
- return this.rpcClient.call("H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */, {
4825
- containerId,
4826
- slotId,
4827
- itemId
4828
- });
4829
- }
4830
- removeItemFromSlotAsync(containerId, slotId) {
4831
- return this.rpcClient.call("H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */, {
4832
- containerId,
4833
- slotId
4834
- });
4835
- }
4836
- async getSlotContainersAsync() {
4837
- const response = await this.rpcClient.call(
4838
- "H5_SIMULATION_GET_CONTAINERS" /* H5_SIMULATION_GET_CONTAINERS */,
4839
- {}
4840
- );
4841
- return response.containers || [];
4842
- }
4843
- async getSlotAssignmentsAsync(containerId) {
4844
- const response = await this.rpcClient.call(
4845
- "H5_SIMULATION_GET_ASSIGNMENTS" /* H5_SIMULATION_GET_ASSIGNMENTS */,
4846
- {
4847
- containerId
4848
- }
4849
- );
4850
- return Array.isArray(response) ? response : response.assignments || [];
4851
- }
4852
- async getStateAsync(roomId) {
4877
+ // Get user's rooms with optional filtering
4878
+ async getUserRoomsAsync(options = {}) {
4853
4879
  const response = await this.rpcClient.call(
4854
- "H5_SIMULATION_GET_STATE" /* H5_SIMULATION_GET_STATE */,
4880
+ "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
4855
4881
  {
4856
- roomId
4882
+ includeArchived: options.includeArchived ?? false
4857
4883
  }
4858
4884
  );
4859
- console.log("[Venus SDK] getStateAsync", response);
4860
- if (response.configuration) {
4861
- this._simulationConfig = response.configuration;
4862
- }
4863
- return response;
4864
- }
4865
- async getConfigAsync(roomId) {
4866
- if (this._simulationConfig) {
4867
- return this._simulationConfig;
4868
- }
4869
- const config = await this.rpcClient.call(
4870
- "H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
4871
- {}
4872
- );
4873
- console.log("[Venus SDK] getConfigAsync", config);
4874
- if (config) {
4875
- this._simulationConfig = config;
4876
- return config;
4885
+ if (response?.success === false) {
4886
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
4887
+ throw new Error(errorMessage);
4877
4888
  }
4878
- throw new Error("No simulation configuration available");
4879
- }
4880
- executeRecipeAsync(recipeId, inputs, options) {
4881
- return this.rpcClient.call("H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */, {
4882
- recipeId,
4883
- inputs,
4884
- roomId: options?.roomId,
4885
- batchAmount: options?.batchAmount,
4886
- allowPartialBatch: options?.allowPartialBatch,
4887
- entity: options?.entity
4888
- });
4889
- }
4890
- collectRecipeAsync(runId) {
4891
- return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
4892
- runId
4893
- });
4894
- }
4895
- getActiveRunsAsync(options) {
4896
- return this.rpcClient.call("H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */, {
4897
- roomId: options?.roomId
4898
- });
4899
- }
4900
- executeScopedRecipeAsync(recipeId, entity, inputs, options) {
4901
- return this.rpcClient.call(
4902
- "H5_SIMULATION_EXECUTE_SCOPED_RECIPE" /* H5_SIMULATION_EXECUTE_SCOPED_RECIPE */,
4903
- {
4904
- recipeId,
4905
- entity,
4906
- inputs,
4907
- roomId: options?.roomId ?? null,
4908
- options
4889
+ const venusRooms = [];
4890
+ for (const roomData of response.rooms) {
4891
+ if (!roomData.id) {
4892
+ console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
4893
+ continue;
4909
4894
  }
4910
- );
4895
+ try {
4896
+ const venusRoom = new VenusRoom(roomData);
4897
+ venusRooms.push(venusRoom);
4898
+ } catch (error) {
4899
+ console.warn(
4900
+ "[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
4901
+ error,
4902
+ roomData
4903
+ );
4904
+ }
4905
+ }
4906
+ return venusRooms;
4911
4907
  }
4912
- getAvailableRecipesAsync(options) {
4913
- return this.rpcClient.call(
4914
- "H5_SIMULATION_GET_AVAILABLE_RECIPES" /* H5_SIMULATION_GET_AVAILABLE_RECIPES */,
4908
+ async updateRoomDataAsync(room, updates, options = {}) {
4909
+ const response = await this.rpcClient.call(
4910
+ "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
4915
4911
  {
4916
- roomId: options?.roomId || null,
4917
- includeActorRecipes: options?.includeActorRecipes || false
4912
+ roomId: room.id,
4913
+ updates,
4914
+ merge: options.merge ?? true
4918
4915
  }
4919
4916
  );
4917
+ if (response?.success === false) {
4918
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
4919
+ throw new Error(errorMessage);
4920
+ }
4920
4921
  }
4921
- getRecipeRequirementsAsync(recipe) {
4922
- return this.rpcClient.call(
4923
- "H5_SIMULATION_GET_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_RECIPE_REQUIREMENTS */,
4922
+ async getRoomDataAsync(room) {
4923
+ const response = await this.rpcClient.call(
4924
+ "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
4924
4925
  {
4925
- recipeId: recipe.recipeId,
4926
- entity: recipe.entity,
4927
- batchAmount: recipe.batchAmount
4926
+ roomId: room.id
4928
4927
  }
4929
4928
  );
4929
+ if (response?.success === false) {
4930
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
4931
+ throw new Error(errorMessage);
4932
+ }
4933
+ return response.data;
4930
4934
  }
4931
- getBatchRecipeRequirementsAsync(recipes) {
4932
- return this.rpcClient.call(
4933
- "H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS */,
4935
+ async sendRoomMessageAsync(venusRoom, request) {
4936
+ const response = await this.rpcClient.call(
4937
+ "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
4934
4938
  {
4935
- recipes
4939
+ roomId: venusRoom.id,
4940
+ message: request.message,
4941
+ metadata: request.metadata
4936
4942
  }
4937
4943
  );
4944
+ if (response?.success === false) {
4945
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
4946
+ throw new Error(errorMessage);
4947
+ }
4948
+ return response.messageId;
4938
4949
  }
4939
- triggerRecipeChainAsync(recipeId, options) {
4940
- return this.rpcClient.call(
4941
- "H5_SIMULATION_TRIGGER_RECIPE_CHAIN" /* H5_SIMULATION_TRIGGER_RECIPE_CHAIN */,
4950
+ async leaveRoomAsync(room) {
4951
+ const response = await this.rpcClient.call(
4952
+ "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
4942
4953
  {
4943
- triggerRecipeId: recipeId,
4944
- context: options?.context,
4945
- roomId: options?.roomId
4954
+ roomId: room.id
4946
4955
  }
4947
4956
  );
4957
+ if (response?.success === false) {
4958
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
4959
+ throw new Error(errorMessage);
4960
+ }
4948
4961
  }
4949
- getEntityMetadataAsync(entityId) {
4950
- return this.rpcClient.call(
4951
- "H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
4962
+ async startRoomGameAsync(room, options = {}) {
4963
+ const response = await this.rpcClient.call(
4964
+ "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
4952
4965
  {
4953
- entityId
4966
+ roomId: room.id,
4967
+ gameConfig: options.gameConfig ?? {},
4968
+ turnOrder: options.turnOrder ?? null
4954
4969
  }
4955
4970
  );
4971
+ if (response?.success === false) {
4972
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
4973
+ throw new Error(errorMessage);
4974
+ }
4956
4975
  }
4957
- async resolveFieldValueAsync(entityId, fieldPath, entity) {
4976
+ async proposeMoveAsync(room, proposalPayload) {
4958
4977
  const response = await this.rpcClient.call(
4959
- "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
4978
+ "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
4960
4979
  {
4961
- entityId,
4962
- fieldPath,
4963
- entity
4980
+ roomId: room.id,
4981
+ gameSpecificState: proposalPayload.gameSpecificState,
4982
+ moveType: proposalPayload.moveType,
4983
+ clientContext: proposalPayload.clientContext,
4984
+ clientProposalId: proposalPayload.clientProposalId
4964
4985
  }
4965
4986
  );
4966
- return response.value;
4967
- }
4968
- };
4969
-
4970
- // src/simulation/MockSimulationApi.ts
4971
- function generateAppIdentifier2() {
4972
- if (typeof window === "undefined") return "unknown-app";
4973
- const url = window.location.href;
4974
- const match = url.match(/\/H5\/([^\/]+)/);
4975
- return match ? match[1] : "unknown-app";
4976
- }
4977
- var MockSimulationApi = class {
4978
- constructor(simulationConfig = null) {
4979
- __publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
4980
- // appIdentifier -> config
4981
- __publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
4982
- // appIdentifier -> config
4983
- __publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
4984
- // appIdentifier -> timers[]
4985
- __publicField(this, "appId");
4986
- __publicField(this, "providedSimulationConfig");
4987
- this.appId = generateAppIdentifier2();
4988
- this.providedSimulationConfig = simulationConfig;
4989
- }
4990
- sumContributions(contributions) {
4991
- return sumContributions(contributions);
4992
- }
4993
- async validateSlotAssignmentAsync(containerId, slotId, itemId) {
4994
- this.log("validateSlotAssignmentAsync called:", {
4995
- containerId,
4996
- slotId,
4997
- itemId
4998
- });
4999
- return { valid: true, message: "Mock validation successful" };
5000
- }
5001
- async executeBatchOperationsAsync(operations, validateOnly) {
5002
- this.log("executeBatchOperationsAsync called:", {
5003
- operations,
5004
- validateOnly
5005
- });
5006
- return {
5007
- success: true,
5008
- results: operations.map(() => ({ success: true }))
5009
- };
5010
- }
5011
- async getAvailableItemsAsync(containerId, slotId) {
5012
- console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
5013
- containerId,
5014
- slotId
5015
- });
5016
- const appIdentifier = generateAppIdentifier2();
5017
- const mockSimulationConfigs = this.mockSimulationConfigs;
5018
- const config = mockSimulationConfigs.get(appIdentifier) || {
5019
- entities: {}
5020
- };
5021
- const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
5022
- entityId,
5023
- quantity: 1,
5024
- metadata: entity.metadata,
5025
- powerPreview: 100
5026
- // Mock power value
5027
- }));
5028
- return availableItems;
5029
- }
5030
- async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
5031
- this.log("calculatePowerPreviewAsync called:", {
5032
- containerId,
5033
- slotId,
5034
- candidateItemId
5035
- });
5036
- return {
5037
- currentPower: 1e3,
5038
- previewPower: 1200,
5039
- powerDelta: 200,
5040
- breakdown: { base: 800, weapon: 200, armor: 200 }
5041
- };
5042
- }
5043
- async getSlotContainersAsync() {
5044
- this.log("getSlotContainersAsync called");
5045
- const appIdentifier = this.appId;
5046
- const mockSimulationConfigs = this.mockSimulationConfigs;
5047
- const config = mockSimulationConfigs.get(appIdentifier) || {
5048
- entities: {}
5049
- };
5050
- const containers = Object.entries(config.entities).filter(([_2, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
5051
- entityId,
5052
- slots: entity.metadata?.slots,
5053
- isOwned: true
5054
- // Mock: assume all containers are owned
5055
- }));
5056
- return containers;
5057
- }
5058
- async getSlotAssignmentsAsync(containerId) {
5059
- this.log("getSlotAssignmentsAsync called for:", containerId);
5060
- return [];
5061
- }
5062
- async resolveFieldValueAsync(entityId, fieldPath, entity) {
5063
- this.log("resolveFieldValueAsync called:", {
5064
- entityId,
5065
- fieldPath,
5066
- entity
5067
- });
5068
- const mockValues = {
5069
- basePower: 850,
5070
- weaponPower: 300,
5071
- armorPower: 150,
5072
- total_power: 1300,
5073
- total_defense_power: 5e3
5074
- };
5075
- return mockValues[fieldPath] || 100;
5076
- }
5077
- async getEntityMetadataAsync(entityId) {
5078
- this.log("getEntityMetadataAsync called for:", entityId);
5079
- const mockSimulationConfigs = this.mockSimulationConfigs;
5080
- const appIdentifier = this.appId;
5081
- const config = mockSimulationConfigs.get(
5082
- appIdentifier
5083
- ) || {
5084
- entities: {}};
5085
- const entity = config.entities[entityId];
5086
- return entity?.metadata || {};
5087
- }
5088
- async collectRecipeAsync(runId) {
5089
- this.log("collectRecipeAsync called:", { runId });
5090
- const mockRewards = {
5091
- cash: Math.floor(Math.random() * 1e3) + 500,
5092
- experience: Math.floor(Math.random() * 50) + 25
5093
- };
5094
- return {
5095
- success: true,
5096
- runId,
5097
- rewards: mockRewards,
5098
- message: "Rewards collected successfully"
5099
- };
5100
- }
5101
- executeRecipeAsync(recipeId, inputs, options) {
5102
- this.log("executeRecipeAsync called:", {
5103
- recipeId,
5104
- inputs,
5105
- options
5106
- });
5107
- const appIdentifier = this.appId;
5108
- return this.executeRecipe(appIdentifier, recipeId, inputs);
5109
- }
5110
- async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
5111
- this.log("executeScopedRecipeAsync called:", {
5112
- recipeId,
5113
- entity,
5114
- inputs,
5115
- roomId: options?.roomId,
5116
- options
5117
- });
5118
- return {
5119
- success: true,
5120
- message: "Mock scoped recipe execution successful"
5121
- };
5122
- }
5123
- async getActiveRunsAsync(options) {
5124
- this.log("getActiveRunsAsync called:", options);
5125
- const appIdentifier = this.appId;
5126
- let state = this.mockSimulationStates.get(appIdentifier);
5127
- if (!state) {
5128
- state = await this.initializeSimulationState(appIdentifier);
5129
- }
5130
- return state.activeRuns || [];
5131
- }
5132
- async getAvailableRecipesAsync(options) {
5133
- this.log("getAvailableRecipesAsync called:", options);
5134
- const baseRecipes = [
5135
- { id: "collect_resources", scope: "player", clientViewable: true },
5136
- { id: "upgrade_equipment", scope: "player", clientViewable: true }
5137
- ];
5138
- if (options?.roomId) {
5139
- baseRecipes.push(
5140
- { id: "room_upgrade", scope: "room", clientViewable: true },
5141
- { id: "cooperative_project", scope: "room", clientViewable: true }
5142
- );
5143
- }
5144
- if (options?.includeActorRecipes && options?.roomId) {
5145
- baseRecipes.push(
5146
- { id: "trade_with_npc", scope: "actor", clientViewable: true },
5147
- { id: "attack_monster", scope: "actor", clientViewable: true }
5148
- );
4987
+ if (response?.success === false) {
4988
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
4989
+ throw new Error(errorMessage);
5149
4990
  }
5150
- return { success: true, recipes: baseRecipes };
5151
- }
5152
- async getBatchRecipeRequirementsAsync(recipes) {
5153
- this.log("getBatchRecipeRequirementsAsync called:", {
5154
- count: recipes?.length
5155
- });
5156
- const results = (recipes || []).map((q) => ({
5157
- recipeId: q.recipeId,
5158
- entity: q.entity || null,
5159
- amount: q.batchAmount || 1,
5160
- inputs: { cash: "BE:0" },
5161
- canAfford: true,
5162
- disabled: false
5163
- }));
5164
- return { success: true, results };
5165
- }
5166
- async getRecipeRequirementsAsync(recipe) {
5167
- this.log("getRecipeRequirementsAsync called:", recipe);
5168
- return {
5169
- recipeId: recipe.recipeId,
5170
- entity: recipe.entity || null,
5171
- amount: recipe.batchAmount,
5172
- inputs: { cash: "BE:0" },
5173
- canAfford: true,
5174
- disabled: false
5175
- };
4991
+ return response.data;
5176
4992
  }
5177
- async triggerRecipeChainAsync(recipeId, options) {
5178
- this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
4993
+ async validateMoveAsync(_room, moveId, verdict) {
5179
4994
  return {
5180
4995
  success: true,
5181
- message: "Mock recipe chain triggered successfully"
4996
+ moveId,
4997
+ isValid: verdict.isValid,
4998
+ reason: verdict.reason
5182
4999
  };
5183
5000
  }
5184
- log(message, ...args) {
5185
- console.log(`[Venus Sim Mock] ${message}`, args);
5186
- }
5187
- async executeRecipe(appIdentifier, recipeId, inputs) {
5188
- this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
5189
- const mockSimulationConfigs = this.mockSimulationConfigs;
5190
- const mockSimulationStates = this.mockSimulationStates;
5191
- let config = mockSimulationConfigs.get(appIdentifier);
5192
- let state = mockSimulationStates.get(appIdentifier);
5193
- if (!config || !state) {
5194
- state = await this.initializeSimulationState(appIdentifier);
5195
- config = mockSimulationConfigs.get(appIdentifier);
5196
- if (!config) {
5197
- throw new Error("Failed to initialize simulation config");
5198
- }
5199
- }
5200
- const recipe = config.recipes?.[recipeId];
5201
- if (!recipe) {
5202
- throw new Error(`Recipe ${recipeId} not found`);
5203
- }
5204
- if (state.disabledRecipes?.includes(recipeId)) {
5205
- throw new Error(`Recipe ${recipeId} is disabled`);
5206
- }
5207
- if (recipe.inputs) {
5208
- for (const [entityId, required] of Object.entries(recipe.inputs)) {
5209
- const available = state.inventory[entityId] || 0;
5210
- if (available < required) {
5211
- throw new Error(
5212
- `Insufficient ${entityId}: required ${required}, available ${available}`
5213
- );
5214
- }
5001
+ async subscribeAsync(room, options = {}) {
5002
+ const roomId = room.id;
5003
+ const existingData = this.subscriptions.data[roomId];
5004
+ const existingMessages = this.subscriptions.messages[roomId];
5005
+ const existingGameEvents = this.subscriptions.gameEvents[roomId];
5006
+ const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
5007
+ const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
5008
+ const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
5009
+ if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
5010
+ try {
5011
+ await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
5012
+ roomId,
5013
+ subscribeToData,
5014
+ subscribeToMessages,
5015
+ subscribeToProposedMoves
5016
+ });
5017
+ } catch (error) {
5018
+ console.error("[Venus SDK] Failed to set up room subscription:", error);
5019
+ throw error;
5215
5020
  }
5216
5021
  }
5217
- if (recipe.inputs) {
5218
- for (const [entityId, input] of Object.entries(recipe.inputs)) {
5219
- const inventoryValue = state.inventory[entityId] || 0;
5220
- if (typeof input === "number" && typeof inventoryValue === "number") {
5221
- state.inventory[entityId] = inventoryValue - input;
5222
- }
5022
+ if (options.onData) {
5023
+ if (!this.subscriptions.data[roomId]) {
5024
+ this.subscriptions.data[roomId] = [];
5223
5025
  }
5026
+ this.subscriptions.data[roomId].push(options.onData);
5224
5027
  }
5225
- if (recipe.beginEffects) {
5226
- this.applyEffects(state, recipe.beginEffects);
5227
- }
5228
- const runId = this.generateRunId();
5229
- const now = Date.now();
5230
- const expiresAt = now + (recipe.duration || 0);
5231
- const run = {
5232
- id: runId,
5233
- recipeId,
5234
- status: "running",
5235
- startTime: now,
5236
- expiresAt,
5237
- inputs: recipe.inputs || {}
5238
- };
5239
- state.activeRuns.push(run);
5240
- if (recipe.duration === 0) {
5241
- this.completeRun(appIdentifier, runId);
5242
- return { status: "completed", runId };
5243
- } else {
5244
- const mockActiveTimers = this.mockActiveTimers;
5245
- const timer = setTimeout(() => {
5246
- this.completeRun(appIdentifier, runId);
5247
- }, recipe.duration);
5248
- const timers = mockActiveTimers.get(appIdentifier) || [];
5249
- timers.push(timer);
5250
- mockActiveTimers.set(appIdentifier, timers);
5251
- return {
5252
- status: "running",
5253
- runId,
5254
- expiresAt: new Date(expiresAt).toISOString()
5255
- };
5256
- }
5257
- }
5258
- async initializeSimulationState(appIdentifier) {
5259
- this.log(`Initializing simulation state for ${appIdentifier}`);
5260
- const providedSimulationConfig = this.providedSimulationConfig;
5261
- const mockSimulationConfigs = this.mockSimulationConfigs;
5262
- const mockSimulationStates = this.mockSimulationStates;
5263
- const mockActiveTimers = this.mockActiveTimers;
5264
- const config = providedSimulationConfig || {
5265
- version: "1.0",
5266
- entities: {},
5267
- recipes: {}
5268
- };
5269
- mockSimulationConfigs.set(appIdentifier, config);
5270
- const initialInventory = {};
5271
- if (providedSimulationConfig && config.entities) {
5272
- Object.keys(config.entities).forEach((entityId) => {
5273
- initialInventory[entityId] = 0;
5274
- });
5028
+ if (options.onMessages) {
5029
+ if (!this.subscriptions.messages[roomId]) {
5030
+ this.subscriptions.messages[roomId] = [];
5031
+ }
5032
+ this.subscriptions.messages[roomId].push(options.onMessages);
5275
5033
  }
5276
- const state = {
5277
- inventory: initialInventory,
5278
- activeRuns: [],
5279
- disabledRecipes: new Array()
5280
- };
5281
- if (config.recipes) {
5282
- Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
5283
- if (recipe.metadata?.startsDisabled) {
5284
- state.disabledRecipes.push(recipeId);
5285
- }
5286
- });
5034
+ if (options.onGameEvents) {
5035
+ if (!this.subscriptions.gameEvents[roomId]) {
5036
+ this.subscriptions.gameEvents[roomId] = [];
5037
+ }
5038
+ this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
5287
5039
  }
5288
- mockSimulationStates.set(appIdentifier, state);
5289
- mockActiveTimers.set(appIdentifier, []);
5290
- console.log(
5291
- `[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
5292
- state
5293
- );
5294
- if (config.recipes) {
5295
- Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
5296
- const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
5297
- if (isAutoRestart && recipe.outputs) {
5298
- this.log(`Found auto-restart recipe: ${recipeId}`, {
5299
- topLevelAutoRestart: recipe.autoRestart,
5300
- metadataAutoRestart: recipe.metadata?.autoRestart,
5301
- hasOutputs: !!recipe.outputs,
5302
- duration: recipe.duration
5303
- });
5304
- const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
5305
- if (condition && condition.entity) {
5306
- const currentAmount = initialInventory[condition.entity] || 0;
5307
- if (currentAmount < condition.maxValue) {
5308
- console.log(
5309
- `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
5310
- {
5311
- currentAmount,
5312
- maxValue: condition.maxValue,
5313
- entity: condition.entity
5314
- }
5315
- );
5316
- setTimeout(() => {
5317
- this.executeRecipe(appIdentifier, recipeId, {});
5318
- }, 1e3);
5319
- }
5320
- } else {
5321
- console.log(
5322
- `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
5323
- );
5324
- setTimeout(() => {
5325
- this.executeRecipe(appIdentifier, recipeId, {});
5326
- }, 1e3);
5040
+ let disposed = false;
5041
+ return () => {
5042
+ if (disposed) return;
5043
+ disposed = true;
5044
+ if (options.onData) {
5045
+ const callbacks = this.subscriptions.data[roomId];
5046
+ if (callbacks) {
5047
+ const index = callbacks.indexOf(options.onData);
5048
+ if (index > -1) {
5049
+ callbacks.splice(index, 1);
5327
5050
  }
5328
5051
  }
5329
- });
5330
- }
5331
- return state;
5332
- }
5333
- generateRunId() {
5334
- return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5335
- }
5336
- completeRun(appIdentifier, runId) {
5337
- this.log(`Completing run ${runId} for ${appIdentifier}`);
5338
- const mockSimulationConfigs = this.mockSimulationConfigs;
5339
- const mockSimulationStates = this.mockSimulationStates;
5340
- const config = mockSimulationConfigs.get(appIdentifier);
5341
- const state = mockSimulationStates.get(appIdentifier);
5342
- if (!config || !state) return;
5343
- const runIndex = state.activeRuns.findIndex((r2) => r2.id === runId);
5344
- if (runIndex === -1) return;
5345
- const run = state.activeRuns[runIndex];
5346
- const recipe = config.recipes?.[run.recipeId];
5347
- if (!recipe) return;
5348
- const outputs = {};
5349
- const rng = this.createSeededRandom(runId);
5350
- if (recipe.outputs) {
5351
- for (const [entityId, value] of Object.entries(recipe.outputs)) {
5352
- if (typeof value === "number") {
5353
- outputs[entityId] = value;
5354
- } else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
5355
- outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
5356
- }
5357
5052
  }
5358
- }
5359
- for (const [entityId, amount] of Object.entries(outputs)) {
5360
- state.inventory[entityId] = (state.inventory[entityId] || 0) + amount;
5361
- }
5362
- if (recipe.endEffects) {
5363
- this.applyEffects(state, recipe.endEffects);
5364
- }
5365
- run.status = "completed";
5366
- run.outputs = outputs;
5367
- state.activeRuns.splice(runIndex, 1);
5368
- const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
5369
- if (isAutoRestart) {
5370
- console.log(
5371
- `[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
5372
- {
5373
- topLevelAutoRestart: recipe.autoRestart,
5374
- metadataAutoRestart: recipe.metadata?.autoRestart,
5375
- hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
5376
- }
5377
- );
5378
- const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
5379
- if (condition) {
5380
- const currentAmount = state.inventory[condition.entity] || 0;
5381
- if (currentAmount < condition.maxValue) {
5382
- console.log(
5383
- `[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
5384
- {
5385
- currentAmount,
5386
- maxValue: condition.maxValue,
5387
- entity: condition.entity
5388
- }
5389
- );
5390
- setTimeout(() => {
5391
- this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
5392
- }, 1e3);
5053
+ if (options.onMessages) {
5054
+ const callbacks = this.subscriptions.messages[roomId];
5055
+ if (callbacks) {
5056
+ const index = callbacks.indexOf(options.onMessages);
5057
+ if (index > -1) {
5058
+ callbacks.splice(index, 1);
5059
+ }
5393
5060
  }
5394
- } else {
5395
- console.log(
5396
- `[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
5397
- );
5398
- setTimeout(() => {
5399
- this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
5400
- }, 1e3);
5401
5061
  }
5402
- }
5403
- console.log(
5404
- `[Venus Simulation Mock] Completed run ${runId}, outputs:`,
5405
- outputs
5406
- );
5407
- }
5408
- createSeededRandom(seed) {
5409
- let hash = 0;
5410
- for (let i = 0; i < seed.length; i++) {
5411
- const char = seed.charCodeAt(i);
5412
- hash = (hash << 5) - hash + char;
5413
- hash = hash & hash;
5414
- }
5415
- return () => {
5416
- hash = (hash * 9301 + 49297) % 233280;
5417
- return hash / 233280;
5418
- };
5419
- }
5420
- applyEffects(state, effects) {
5421
- if (!effects || !Array.isArray(effects)) return;
5422
- for (const effect of effects) {
5423
- switch (effect.type) {
5424
- case "set":
5425
- state.inventory[effect.target] = effect.value;
5426
- console.log(
5427
- `[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
5428
- );
5429
- break;
5430
- case "add":
5431
- state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
5432
- console.log(
5433
- `[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
5434
- );
5435
- break;
5436
- case "multiply":
5437
- state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
5438
- console.log(
5439
- `[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
5440
- );
5441
- break;
5442
- case "min":
5443
- state.inventory[effect.target] = Math.max(
5444
- state.inventory[effect.target] || 0,
5445
- effect.value
5446
- );
5447
- console.log(
5448
- `[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
5449
- );
5450
- break;
5451
- case "max":
5452
- state.inventory[effect.target] = Math.min(
5453
- state.inventory[effect.target] || 0,
5454
- effect.value
5455
- );
5456
- console.log(
5457
- `[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
5458
- );
5459
- break;
5460
- case "enable_recipe":
5461
- if (state.disabledRecipes?.includes(effect.target)) {
5462
- state.disabledRecipes = state.disabledRecipes.filter(
5463
- (r2) => r2 !== effect.target
5464
- );
5465
- console.log(
5466
- `[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
5467
- );
5062
+ if (options.onGameEvents) {
5063
+ const callbacks = this.subscriptions.gameEvents[roomId];
5064
+ if (callbacks) {
5065
+ const index = callbacks.indexOf(options.onGameEvents);
5066
+ if (index > -1) {
5067
+ callbacks.splice(index, 1);
5468
5068
  }
5469
- break;
5470
- case "disable_recipe":
5471
- if (!state.disabledRecipes) state.disabledRecipes = [];
5472
- if (!state.disabledRecipes.includes(effect.target)) {
5473
- state.disabledRecipes.push(effect.target);
5474
- console.log(
5475
- `[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
5476
- );
5477
- }
5478
- break;
5479
- case "trigger_recipe":
5480
- console.log(
5481
- `[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
5482
- );
5483
- break;
5484
- default:
5485
- console.warn(
5486
- `[Venus Simulation Mock] Unknown effect type: ${effect.type}`
5487
- );
5069
+ }
5070
+ }
5071
+ const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
5072
+ if (!hasAnySubscriptions) {
5073
+ this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
5074
+ roomId
5075
+ }).catch((error) => {
5076
+ console.error("[Venus SDK] Failed to clean up room subscription:", error);
5077
+ });
5488
5078
  }
5489
- }
5490
- }
5491
- async getConfigAsync() {
5492
- console.log("[Venus Simulation Mock] getConfigAsync called");
5493
- const appIdentifier = this.appId;
5494
- const mockSimulationConfigs = this.mockSimulationConfigs;
5495
- const config = mockSimulationConfigs.get(appIdentifier) || {
5496
- version: "1.0",
5497
- entities: {},
5498
- recipes: {}
5499
- };
5500
- return config;
5501
- }
5502
- async getStateAsync(roomId) {
5503
- this.log("getStateAsync called:", roomId);
5504
- const appIdentifier = this.appId;
5505
- const mockSimulationStates = this.mockSimulationStates;
5506
- let state = mockSimulationStates.get(appIdentifier);
5507
- if (!state) {
5508
- state = await this.initializeSimulationState(appIdentifier);
5509
- }
5510
- const mockSimulationConfigs = this.mockSimulationConfigs;
5511
- return {
5512
- ...state,
5513
- roomId,
5514
- configuration: mockSimulationConfigs.get(appIdentifier)
5515
5079
  };
5516
5080
  }
5517
- async assignItemToSlotAsync(containerId, slotId, itemId) {
5518
- this.log("assignItemToSlotAsync called:", {
5519
- containerId,
5520
- slotId,
5521
- itemId
5522
- });
5523
- return { success: true, message: "Mock assignment successful" };
5524
- }
5525
- async removeItemFromSlotAsync(containerId, slotId) {
5526
- this.log("removeItemFromSlotAsync called:", {
5527
- containerId,
5528
- slotId
5529
- });
5530
- return { success: true, message: "Mock removal successful" };
5531
- }
5532
5081
  };
5533
5082
 
5534
- // src/simulation/index.ts
5535
- function initializeSimulation(venusApi, host) {
5536
- console.log("[Venus SDK] Initializing new Simulation Api");
5537
- venusApi.simulation = {
5538
- isEnabled: () => true
5539
- };
5540
- venusApi.simulation.getConfigAsync = () => {
5541
- return host.simulation.getConfigAsync();
5542
- };
5543
- venusApi.simulation.getStateAsync = (options) => {
5544
- return host.simulation.getStateAsync(options?.roomId);
5545
- };
5546
- venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
5547
- return host.simulation.executeRecipeAsync(recipeId, inputs, options);
5548
- };
5549
- venusApi.simulation.getActiveRunsAsync = () => {
5550
- return host.simulation.getActiveRunsAsync();
5551
- };
5552
- venusApi.simulation.collectRecipeAsync = (runId) => {
5553
- return host.simulation.collectRecipeAsync(runId);
5554
- };
5555
- venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, roomId, options) => {
5556
- return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, {
5557
- roomId,
5558
- ...options
5559
- });
5560
- };
5561
- venusApi.simulation.triggerRecipeChainAsync = (recipeId, context, roomId) => {
5562
- return host.simulation.triggerRecipeChainAsync(recipeId, {
5563
- context,
5564
- roomId
5565
- });
5566
- };
5567
- venusApi.simulation.getAvailableRecipesAsync = async (roomId, includeActorRecipes) => {
5568
- const result = await host.simulation.getAvailableRecipesAsync({
5569
- roomId,
5570
- includeActorRecipes
5571
- });
5572
- return result.recipes;
5573
- };
5574
- venusApi.simulation.getRecipeRequirementsAsync = (recipeId, entity, amount) => {
5575
- return host.simulation.getRecipeRequirementsAsync({
5576
- recipeId,
5577
- entity,
5578
- batchAmount: amount
5579
- });
5580
- };
5581
- venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
5582
- return host.simulation.getBatchRecipeRequirementsAsync(recipes);
5583
- };
5584
- venusApi.simulation.resolveFieldValueAsync = (entityId, fieldPath, entity) => {
5585
- return host.simulation.resolveFieldValueAsync(entityId, fieldPath, entity);
5586
- };
5587
- venusApi.simulation.getEntityMetadataAsync = (entityId) => {
5588
- return host.simulation.getEntityMetadataAsync(entityId);
5589
- };
5590
- venusApi.simulation.getSlotAssignmentsAsync = (containerId) => {
5591
- return host.simulation.getSlotAssignmentsAsync(containerId);
5592
- };
5593
- venusApi.simulation.getSlotContainersAsync = () => {
5594
- return host.simulation.getSlotContainersAsync();
5595
- };
5596
- venusApi.simulation.assignItemToSlotAsync = (containerId, slotId, itemId) => {
5597
- return host.simulation.assignItemToSlotAsync(containerId, slotId, itemId);
5598
- };
5599
- venusApi.simulation.removeItemFromSlotAsync = (containerId, slotId) => {
5600
- return host.simulation.removeItemFromSlotAsync(containerId, slotId);
5601
- };
5602
- venusApi.simulation.getAvailableItemsAsync = (containerId, slotId) => {
5603
- return host.simulation.getAvailableItemsAsync(containerId, slotId);
5604
- };
5605
- venusApi.simulation.calculatePowerPreviewAsync = (containerId, slotId, candidateItemId) => {
5606
- return host.simulation.calculatePowerPreviewAsync(
5607
- containerId,
5608
- slotId,
5609
- candidateItemId
5610
- );
5611
- };
5612
- venusApi.simulation.executeBatchOperationsAsync = (operations, validateOnly) => {
5613
- return host.simulation.executeBatchOperationsAsync(operations, validateOnly);
5614
- };
5615
- venusApi.simulation.validateSlotAssignmentAsync = (containerId, slotId, itemId) => {
5616
- return host.simulation.validateSlotAssignmentAsync(
5617
- containerId,
5618
- slotId,
5619
- itemId
5083
+ // src/rooms/index.ts
5084
+ function bindMethod(target, targetKey, source, sourceKey) {
5085
+ const key = sourceKey ?? targetKey;
5086
+ const fn = source?.[key];
5087
+ if (typeof fn === "function") {
5088
+ target[targetKey] = fn.bind(source);
5089
+ return true;
5090
+ }
5091
+ return false;
5092
+ }
5093
+ function initializeRoomsApi(venusApi, host) {
5094
+ const roomsApi = host?.rooms;
5095
+ if (!roomsApi) {
5096
+ console.warn(
5097
+ "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
5620
5098
  );
5621
- };
5622
- venusApi.simulation.sumContributions = (contributions) => {
5623
- return host.simulation.sumContributions(contributions);
5624
- };
5099
+ return;
5100
+ }
5101
+ const venus = venusApi;
5102
+ const existingNamespace = venus.rooms || {};
5103
+ const roomsNamespace = Object.assign({}, existingNamespace);
5104
+ const namespaceBindings = [
5105
+ ["createRoomAsync"],
5106
+ ["joinOrCreateRoomAsync"],
5107
+ ["joinRoomByCodeAsync"],
5108
+ ["getUserRoomsAsync"],
5109
+ ["subscribeAsync"],
5110
+ ["updateRoomDataAsync"],
5111
+ ["getRoomDataAsync"],
5112
+ ["sendRoomMessageAsync"],
5113
+ ["leaveRoomAsync"],
5114
+ ["startRoomGameAsync"],
5115
+ ["proposeMoveAsync"],
5116
+ ["validateMoveAsync"]
5117
+ ];
5118
+ namespaceBindings.forEach(([targetKey, sourceKey]) => {
5119
+ bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
5120
+ });
5121
+ venus.rooms = roomsNamespace;
5625
5122
  }
5626
5123
 
5627
- // src/MockHost.ts
5628
- init_rooms();
5629
-
5630
5124
  // src/logging/MockLoggingApi.ts
5631
5125
  var MockLoggingApi = class {
5632
5126
  logDebug(message, ...args) {
@@ -5702,9 +5196,16 @@ function initializeLoggingApi(venusApi, host) {
5702
5196
  };
5703
5197
  }
5704
5198
 
5705
- // src/shared-assets/consts.ts
5706
- var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
5707
- var CharacterAssetsCdnPath = "burger-time/Character.stow";
5199
+ // src/shared-assets/base64Utils.ts
5200
+ function base64ToArrayBuffer(base64) {
5201
+ const binaryString = atob(base64);
5202
+ const len = binaryString.length;
5203
+ const bytes = new Uint8Array(len);
5204
+ for (let i = 0; i < len; i++) {
5205
+ bytes[i] = binaryString.charCodeAt(i);
5206
+ }
5207
+ return bytes.buffer;
5208
+ }
5708
5209
 
5709
5210
  // src/shared-assets/RpcSharedAssetsApi.ts
5710
5211
  var RpcSharedAssetsApi = class {
@@ -5714,46 +5215,22 @@ var RpcSharedAssetsApi = class {
5714
5215
  this.rpcClient = rpcClient;
5715
5216
  this.venusApi = venusApi;
5716
5217
  }
5717
- async loadBurgerTimeAssetsBundle() {
5718
- try {
5719
- const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
5720
- assetKey: "burgerTimeCoreBundle"
5721
- });
5722
- return base64ToArrayBuffer(response.base64Data);
5723
- } catch (err) {
5724
- try {
5725
- const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
5726
- return await blob.arrayBuffer();
5727
- } catch (e) {
5728
- throw new Error("Failed to load burgerTimeAssetsBundle");
5729
- }
5730
- }
5731
- }
5732
- async loadCharactersBundle() {
5218
+ async loadAssetsBundle(game, bundleKey, fileType = "stow") {
5733
5219
  try {
5734
5220
  const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
5735
- assetKey: "characters"
5221
+ assetKey: bundleKey
5736
5222
  });
5737
5223
  return base64ToArrayBuffer(response.base64Data);
5738
5224
  } catch (err) {
5739
5225
  try {
5740
- const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
5226
+ const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
5741
5227
  return await blob.arrayBuffer();
5742
5228
  } catch (e) {
5743
- throw new Error("Failed to load charactersBundle");
5229
+ throw new Error(`Failed to load ${bundleKey}`);
5744
5230
  }
5745
5231
  }
5746
5232
  }
5747
5233
  };
5748
- function base64ToArrayBuffer(base64) {
5749
- const binaryString = atob(base64);
5750
- const len = binaryString.length;
5751
- const bytes = new Uint8Array(len);
5752
- for (let i = 0; i < len; i++) {
5753
- bytes[i] = binaryString.charCodeAt(i);
5754
- }
5755
- return bytes.buffer;
5756
- }
5757
5234
 
5758
5235
  // src/shared-assets/MockSharedAssetsApi.ts
5759
5236
  var MockSharedAssetsApi = class {
@@ -5761,16 +5238,142 @@ var MockSharedAssetsApi = class {
5761
5238
  __publicField(this, "venusApi");
5762
5239
  this.venusApi = venusApi;
5763
5240
  }
5764
- async loadBurgerTimeAssetsBundle() {
5765
- const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
5766
- return await blob.arrayBuffer();
5767
- }
5768
- async loadCharactersBundle() {
5769
- const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
5241
+ async loadAssetsBundle(game, bundleKey, fileType = "stow") {
5242
+ const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
5770
5243
  return await blob.arrayBuffer();
5771
5244
  }
5772
5245
  };
5773
5246
 
5247
+ // src/shared-assets/embeddedLibrariesManifest.ts
5248
+ var EMBEDDED_LIBRARIES = [
5249
+ {
5250
+ libraryKey: "phaser@3.90.0",
5251
+ assetKey: "library:phaser@3.90.0",
5252
+ packageName: "phaser",
5253
+ version: "3.90.0",
5254
+ globalVar: "Phaser",
5255
+ cdnPath: "phaser/3.90.0/phaser.min.js",
5256
+ moduleSpecifiers: [{ match: "exact", value: "phaser" }],
5257
+ loadStage: 0,
5258
+ enabled: true
5259
+ },
5260
+ {
5261
+ libraryKey: "react@18.3.1",
5262
+ assetKey: "library:react@18.3.1",
5263
+ packageName: "react",
5264
+ version: "18.3.1",
5265
+ globalVar: "React",
5266
+ cdnPath: "react/18.3.1/react.production.min.js",
5267
+ moduleSpecifiers: [
5268
+ { match: "exact", value: "react", behavior: "namespace" },
5269
+ { match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
5270
+ {
5271
+ match: "exact",
5272
+ value: "react/jsx-dev-runtime",
5273
+ behavior: "react-jsx-dev-runtime"
5274
+ }
5275
+ ],
5276
+ loadStage: 0,
5277
+ // Must load before ReactDOM
5278
+ enabled: true
5279
+ },
5280
+ {
5281
+ libraryKey: "react-dom@18.3.1",
5282
+ assetKey: "library:react-dom@18.3.1",
5283
+ packageName: "react-dom",
5284
+ version: "18.3.1",
5285
+ globalVar: "ReactDOM",
5286
+ cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
5287
+ moduleSpecifiers: [
5288
+ { match: "exact", value: "react-dom", behavior: "namespace" },
5289
+ { match: "exact", value: "react-dom/client", behavior: "namespace" }
5290
+ ],
5291
+ loadStage: 1,
5292
+ // Depends on React (stage 0)
5293
+ enabled: true
5294
+ },
5295
+ {
5296
+ libraryKey: "three@0.170.0",
5297
+ assetKey: "library:three@0.170.0",
5298
+ packageName: "three",
5299
+ version: "0.170.0",
5300
+ globalVar: "THREE",
5301
+ cdnPath: "three/r170/three.min.js",
5302
+ moduleSpecifiers: [
5303
+ { match: "exact", value: "three", behavior: "namespace" },
5304
+ { match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
5305
+ ],
5306
+ loadStage: 0,
5307
+ enabled: true
5308
+ },
5309
+ {
5310
+ libraryKey: "matter-js@0.19.0",
5311
+ assetKey: "library:matter-js@0.19.0",
5312
+ packageName: "matter-js",
5313
+ version: "0.19.0",
5314
+ globalVar: "Matter",
5315
+ cdnPath: "matter-js/0.19.0/matter.min.js",
5316
+ moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
5317
+ loadStage: 0,
5318
+ enabled: true
5319
+ },
5320
+ {
5321
+ libraryKey: "inkjs@2.2.0",
5322
+ assetKey: "library:inkjs@2.2.0",
5323
+ packageName: "inkjs",
5324
+ version: "2.2.0",
5325
+ globalVar: "inkjs",
5326
+ cdnPath: "inkjs/2.2.0/ink.min.js",
5327
+ moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
5328
+ loadStage: 0,
5329
+ enabled: true
5330
+ },
5331
+ {
5332
+ libraryKey: "zustand@5.0.3",
5333
+ assetKey: "library:zustand@5.0.3",
5334
+ packageName: "zustand",
5335
+ version: "5.0.3",
5336
+ globalVar: "zustand",
5337
+ cdnPath: "zustand/5.0.3/zustand.min.js",
5338
+ moduleSpecifiers: [
5339
+ { match: "exact", value: "zustand" },
5340
+ { match: "exact", value: "zustand/middleware" }
5341
+ ],
5342
+ loadStage: 0,
5343
+ enabled: true
5344
+ },
5345
+ {
5346
+ libraryKey: "ammo.js@2024.11",
5347
+ assetKey: "library:ammo.js@2024.11",
5348
+ packageName: "ammo.js",
5349
+ version: "2024.11",
5350
+ globalVar: "Ammo",
5351
+ cdnPath: "ammo/2024.11/ammo.js",
5352
+ moduleSpecifiers: [
5353
+ { match: "exact", value: "ammo.js" },
5354
+ { match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
5355
+ ],
5356
+ loadStage: 0,
5357
+ enabled: false
5358
+ // Not ready yet - WASM loading needs additional work
5359
+ }
5360
+ ];
5361
+ EMBEDDED_LIBRARIES.reduce(
5362
+ (acc, lib) => {
5363
+ acc[lib.libraryKey] = lib;
5364
+ return acc;
5365
+ },
5366
+ {}
5367
+ );
5368
+ EMBEDDED_LIBRARIES.filter(
5369
+ (lib) => lib.enabled
5370
+ ).flatMap(
5371
+ (lib) => lib.moduleSpecifiers.map((specifier) => ({
5372
+ ...specifier,
5373
+ libraryKey: lib.libraryKey
5374
+ }))
5375
+ );
5376
+
5774
5377
  // src/game-preloader/MockPreloaderApi.ts
5775
5378
  var MockPreloaderApi = class {
5776
5379
  async showLoadScreen() {
@@ -5848,44 +5451,116 @@ var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when ru
5848
5451
  function createUnavailableRoomsApi() {
5849
5452
  const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
5850
5453
  return {
5851
- async createRoom() {
5454
+ async createRoomAsync() {
5852
5455
  throw roomsUnavailableError();
5853
5456
  },
5854
- async joinOrCreateRoom() {
5457
+ async joinOrCreateRoomAsync() {
5855
5458
  throw roomsUnavailableError();
5856
5459
  },
5857
- async getUserRooms() {
5460
+ async joinRoomByCodeAsync() {
5858
5461
  throw roomsUnavailableError();
5859
5462
  },
5860
- async joinRoomByCode() {
5463
+ async getUserRoomsAsync() {
5861
5464
  throw roomsUnavailableError();
5862
5465
  },
5863
- subscribe() {
5466
+ async subscribeAsync() {
5864
5467
  throw roomsUnavailableError();
5865
5468
  },
5866
- async updateData() {
5469
+ async updateRoomDataAsync() {
5867
5470
  throw roomsUnavailableError();
5868
5471
  },
5869
- async getData() {
5472
+ async getRoomDataAsync() {
5870
5473
  throw roomsUnavailableError();
5871
5474
  },
5872
- async sendMessage() {
5475
+ async sendRoomMessageAsync() {
5873
5476
  throw roomsUnavailableError();
5874
5477
  },
5875
- async leave() {
5478
+ async leaveRoomAsync() {
5876
5479
  throw roomsUnavailableError();
5877
5480
  },
5878
- async startGame() {
5481
+ async startRoomGameAsync() {
5879
5482
  throw roomsUnavailableError();
5880
5483
  },
5881
- async proposeMove() {
5484
+ async proposeMoveAsync() {
5882
5485
  throw roomsUnavailableError();
5883
5486
  },
5884
- async validateMove() {
5487
+ async validateMoveAsync() {
5885
5488
  throw roomsUnavailableError();
5886
5489
  }
5887
5490
  };
5888
5491
  }
5492
+ var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
5493
+ function createUnavailableSimulationApi() {
5494
+ const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
5495
+ return {
5496
+ isEnabled() {
5497
+ return false;
5498
+ },
5499
+ async getStateAsync() {
5500
+ throw simulationUnavailableError();
5501
+ },
5502
+ async getConfigAsync() {
5503
+ throw simulationUnavailableError();
5504
+ },
5505
+ async executeRecipeAsync() {
5506
+ throw simulationUnavailableError();
5507
+ },
5508
+ async getActiveRunsAsync() {
5509
+ throw simulationUnavailableError();
5510
+ },
5511
+ async collectRecipeAsync() {
5512
+ throw simulationUnavailableError();
5513
+ },
5514
+ async executeScopedRecipeAsync() {
5515
+ throw simulationUnavailableError();
5516
+ },
5517
+ async triggerRecipeChainAsync() {
5518
+ throw simulationUnavailableError();
5519
+ },
5520
+ async getAvailableRecipesAsync() {
5521
+ throw simulationUnavailableError();
5522
+ },
5523
+ async getRecipeRequirementsAsync() {
5524
+ throw simulationUnavailableError();
5525
+ },
5526
+ async getBatchRecipeRequirementsAsync() {
5527
+ throw simulationUnavailableError();
5528
+ },
5529
+ async resolveFieldValueAsync() {
5530
+ throw simulationUnavailableError();
5531
+ },
5532
+ async getEntityMetadataAsync() {
5533
+ throw simulationUnavailableError();
5534
+ },
5535
+ async getSlotContainersAsync() {
5536
+ throw simulationUnavailableError();
5537
+ },
5538
+ async getSlotAssignmentsAsync() {
5539
+ throw simulationUnavailableError();
5540
+ },
5541
+ async assignItemToSlotAsync() {
5542
+ throw simulationUnavailableError();
5543
+ },
5544
+ async removeItemFromSlotAsync() {
5545
+ throw simulationUnavailableError();
5546
+ },
5547
+ async getAvailableItemsAsync() {
5548
+ throw simulationUnavailableError();
5549
+ },
5550
+ async calculatePowerPreviewAsync() {
5551
+ throw simulationUnavailableError();
5552
+ },
5553
+ async validateSlotAssignmentAsync() {
5554
+ throw simulationUnavailableError();
5555
+ },
5556
+ async executeBatchOperationsAsync() {
5557
+ throw simulationUnavailableError();
5558
+ },
5559
+ async subscribeAsync() {
5560
+ throw simulationUnavailableError();
5561
+ }
5562
+ };
5563
+ }
5889
5564
  var MockHost = class {
5890
5565
  constructor(venusApi) {
5891
5566
  __publicField(this, "ads");
@@ -5898,9 +5573,9 @@ var MockHost = class {
5898
5573
  __publicField(this, "notifications");
5899
5574
  __publicField(this, "popups");
5900
5575
  __publicField(this, "profile");
5576
+ __publicField(this, "system");
5901
5577
  __publicField(this, "cdn");
5902
5578
  __publicField(this, "time");
5903
- __publicField(this, "post");
5904
5579
  __publicField(this, "ai");
5905
5580
  __publicField(this, "haptics");
5906
5581
  __publicField(this, "features");
@@ -5932,15 +5607,17 @@ var MockHost = class {
5932
5607
  this.navigation = new MockNavigationApi(venusApi);
5933
5608
  this.notifications = new MockNotificationsApi(venusApi);
5934
5609
  this.popups = new MockPopupsApi(this._overlay);
5935
- this.profile = new MockProfileApi();
5936
- this.cdn = new MockCdnApi();
5610
+ this.profile = new MockProfileApi(venusApi);
5611
+ const deviceApi = new MockDeviceApi(venusApi);
5612
+ const environmentApi = new MockEnvironmentApi(venusApi);
5613
+ this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
5614
+ this.cdn = new MockCdnApi(venusApi);
5937
5615
  this.time = new MockTimeApi(venusApi);
5938
- this.post = new MockPostApi(venusApi);
5939
5616
  this.ai = new MockAiApi();
5940
5617
  this.haptics = new MockHapticsApi(venusApi);
5941
5618
  this.features = new MockFeaturesApi();
5942
5619
  this.lifecycle = this._mockLifecyclesApi;
5943
- this.simulation = new MockSimulationApi();
5620
+ this.simulation = createUnavailableSimulationApi();
5944
5621
  this.rooms = createUnavailableRoomsApi();
5945
5622
  this.logging = new MockLoggingApi();
5946
5623
  this.iap = new MockIapApi();
@@ -5956,40 +5633,17 @@ var MockHost = class {
5956
5633
  }
5957
5634
  initialize(options) {
5958
5635
  this._isInitialized = true;
5959
- const controls = this.updateUiControls();
5636
+ this.venusApi._profileData = this.profile.getCurrentProfile();
5637
+ this.venusApi._deviceData = this.system.getDevice();
5638
+ this.venusApi._environmentData = this.system.getEnvironment();
5639
+ this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
5640
+ this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
5960
5641
  return Promise.resolve({
5961
5642
  initializeAsleep: false,
5962
- hudInsets: {
5963
- top: controls.feedHeader.height,
5964
- bottom: 0,
5965
- left: 0,
5966
- right: 0
5967
- }
5643
+ safeArea: this.venusApi._safeAreaData
5968
5644
  });
5969
5645
  }
5970
- updateUiControls() {
5971
- const controls = {
5972
- closeButton: { x: 16, y: 16, width: 32, height: 32 },
5973
- menuButton: {
5974
- x: window.innerWidth - 48,
5975
- y: 16,
5976
- width: 32,
5977
- height: 32
5978
- },
5979
- feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
5980
- playButton: {
5981
- x: 0,
5982
- y: window.innerHeight - 60,
5983
- width: window.innerWidth,
5984
- height: 60
5985
- }
5986
- };
5987
- return controls;
5988
- }
5989
5646
  createOverlay() {
5990
- const venusApi = this.venusApi;
5991
- venusApi.config.ui.controls = this.updateUiControls();
5992
- const uiControls = venusApi.config.ui.controls;
5993
5647
  const overlayContainer = document.createElement("div");
5994
5648
  overlayContainer.id = "venus-mock-overlay";
5995
5649
  overlayContainer.style.cssText = `
@@ -6005,7 +5659,7 @@ var MockHost = class {
6005
5659
  const menuButton = this.createOverlayButton(
6006
5660
  "close",
6007
5661
  "Menu",
6008
- uiControls.menuButton,
5662
+ { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
6009
5663
  () => {
6010
5664
  this.handleMenuButtonClicked();
6011
5665
  },
@@ -6234,17 +5888,13 @@ var MockHost = class {
6234
5888
  return button;
6235
5889
  }
6236
5890
  updateOverlayLayout() {
6237
- const venusApi = this.venusApi;
6238
5891
  const overlay = this._overlay;
6239
- venusApi.config.ui.controls = this.updateUiControls();
6240
- const uiControls = venusApi.config.ui.controls;
6241
5892
  const menuBtn = overlay.elements.menuButton;
6242
- const menuPos = uiControls.menuButton;
6243
- menuBtn.style.left = `${menuPos.x}px`;
6244
- menuBtn.style.top = `${menuPos.y}px`;
6245
- menuBtn.style.width = `${menuPos.width}px`;
6246
- menuBtn.style.minWidth = `${menuPos.width}px`;
6247
- menuBtn.style.height = `${menuPos.height}px`;
5893
+ menuBtn.style.left = `${window.innerWidth - 48}px`;
5894
+ menuBtn.style.top = "16px";
5895
+ menuBtn.style.width = "32px";
5896
+ menuBtn.style.minWidth = "32px";
5897
+ menuBtn.style.height = "32px";
6248
5898
  }
6249
5899
  triggerLifecycleEvent(name) {
6250
5900
  console.log("Trigger Lifecycle Event: ", name);
@@ -6432,6 +6082,11 @@ var MockHost = class {
6432
6082
  }
6433
6083
  };
6434
6084
 
6085
+ // src/utils/idGenerator.ts
6086
+ function generateId() {
6087
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
6088
+ }
6089
+
6435
6090
  // src/rpc/RpcClient.ts
6436
6091
  var RpcClient = class {
6437
6092
  constructor() {
@@ -6474,7 +6129,7 @@ var RpcClient = class {
6474
6129
  }
6475
6130
  async call(method, args, timeout = 5e3) {
6476
6131
  return new Promise((resolve, reject) => {
6477
- const id = this.generateId();
6132
+ const id = generateId();
6478
6133
  this.addPendingCall(id, resolve, reject);
6479
6134
  const request = {
6480
6135
  type: "rpc-request",
@@ -6511,9 +6166,6 @@ var RpcClient = class {
6511
6166
  getPendingCall(id) {
6512
6167
  return this.pendingCalls.get(id);
6513
6168
  }
6514
- generateId() {
6515
- return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
6516
- }
6517
6169
  handleRpcResponse(response) {
6518
6170
  const pending = this.getPendingCall(response.id);
6519
6171
  if (!pending) {
@@ -6576,6 +6228,16 @@ var VenusTransport = class {
6576
6228
  this.isProcessingMessage = false;
6577
6229
  return;
6578
6230
  }
6231
+ if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
6232
+ const notification = {
6233
+ type: "rpc-notification",
6234
+ id: message.type,
6235
+ payload: message.data
6236
+ };
6237
+ this.handleNotification(notification);
6238
+ this.isProcessingMessage = false;
6239
+ return;
6240
+ }
6579
6241
  const requestId = messageData.requestId;
6580
6242
  if (!requestId) {
6581
6243
  this.logWarn("No requestId. Ignoring message...");
@@ -6742,294 +6404,361 @@ var VenusTransport = class {
6742
6404
  }
6743
6405
  };
6744
6406
 
6745
- // src/RemoteHost.ts
6746
- init_rooms();
6747
-
6748
- // src/rooms/RpcRoomsApi.ts
6749
- init_VenusRoom();
6750
- var RpcRoomsApi = class {
6407
+ // src/simulation/RpcSimulationApi.ts
6408
+ var RpcSimulationApi = class {
6751
6409
  constructor(rpcClient) {
6752
6410
  __publicField(this, "rpcClient");
6753
- __publicField(this, "subscriptions");
6754
- __publicField(this, "transportSubscription", null);
6411
+ __publicField(this, "_simulationConfig", null);
6412
+ __publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
6755
6413
  this.rpcClient = rpcClient;
6756
- this.subscriptions = {
6757
- data: {},
6758
- messages: {},
6759
- gameEvents: {},
6760
- allEvents: {}
6761
- };
6414
+ this.rpcClient.onNotification(
6415
+ "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
6416
+ this.handleSimulationUpdate.bind(this)
6417
+ );
6762
6418
  }
6763
- /**
6764
- * Get the subscription state for external access (used by setupRoomNotifications)
6765
- */
6766
- getSubscriptions() {
6767
- return this.subscriptions;
6419
+ isEnabled() {
6420
+ return true;
6768
6421
  }
6769
- /**
6770
- * Set up room notification routing from the transport
6771
- */
6772
- setupNotifications(transport) {
6773
- const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
6774
- this.transportSubscription = setupRoomNotifications2(
6775
- transport,
6776
- () => this.getSubscriptions()
6422
+ async validateSlotAssignmentAsync(containerId, slotId, itemId) {
6423
+ return this.rpcClient.call(
6424
+ "H5_SIMULATION_VALIDATE_ASSIGNMENT" /* H5_SIMULATION_VALIDATE_ASSIGNMENT */,
6425
+ {
6426
+ containerId,
6427
+ slotId,
6428
+ itemId
6429
+ }
6777
6430
  );
6778
6431
  }
6779
- /**
6780
- * Clean up subscriptions and resources
6781
- */
6782
- dispose() {
6783
- if (this.transportSubscription) {
6784
- this.transportSubscription.unsubscribe();
6785
- this.transportSubscription = null;
6786
- console.log("[Venus Rooms] Cleaned up room notification subscription");
6432
+ async subscribeAsync(options) {
6433
+ this.ensureValidSubscribeOptions(options);
6434
+ const subscriptionId = generateId();
6435
+ this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
6436
+ try {
6437
+ await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
6438
+ subscriptionId,
6439
+ entities: options.entities,
6440
+ tags: options.tags,
6441
+ activeRuns: options.activeRuns,
6442
+ roomId: options.roomId
6443
+ });
6444
+ } catch (error) {
6445
+ this.subscriptionCallbacks.delete(subscriptionId);
6446
+ throw error;
6787
6447
  }
6448
+ let unsubscribed = false;
6449
+ return () => {
6450
+ if (unsubscribed) {
6451
+ return;
6452
+ }
6453
+ unsubscribed = true;
6454
+ this.subscriptionCallbacks.delete(subscriptionId);
6455
+ void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
6456
+ subscriptionId
6457
+ }).catch((error) => {
6458
+ console.error(
6459
+ "[Venus SDK] Failed to unsubscribe simulation listener",
6460
+ error
6461
+ );
6462
+ });
6463
+ };
6464
+ }
6465
+ executeBatchOperationsAsync(operations, validateOnly) {
6466
+ return this.rpcClient.call(
6467
+ "H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
6468
+ {
6469
+ operations,
6470
+ validateOnly
6471
+ }
6472
+ );
6788
6473
  }
6789
- async createRoom(options) {
6474
+ async getAvailableItemsAsync(containerId, slotId) {
6790
6475
  const response = await this.rpcClient.call(
6791
- "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
6476
+ "H5_SIMULATION_GET_AVAILABLE_ITEMS" /* H5_SIMULATION_GET_AVAILABLE_ITEMS */,
6792
6477
  {
6793
- options
6478
+ containerId,
6479
+ slotId
6480
+ }
6481
+ );
6482
+ return response.availableItems || [];
6483
+ }
6484
+ calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
6485
+ return this.rpcClient.call(
6486
+ "H5_SIMULATION_CALCULATE_POWER_PREVIEW" /* H5_SIMULATION_CALCULATE_POWER_PREVIEW */,
6487
+ {
6488
+ containerId,
6489
+ slotId,
6490
+ candidateItemId
6491
+ }
6492
+ );
6493
+ }
6494
+ assignItemToSlotAsync(containerId, slotId, itemId) {
6495
+ return this.rpcClient.call(
6496
+ "H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
6497
+ {
6498
+ containerId,
6499
+ slotId,
6500
+ itemId
6501
+ }
6502
+ );
6503
+ }
6504
+ removeItemFromSlotAsync(containerId, slotId) {
6505
+ return this.rpcClient.call(
6506
+ "H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
6507
+ {
6508
+ containerId,
6509
+ slotId
6794
6510
  }
6795
6511
  );
6796
- if (response.success === false) {
6797
- throw new Error(response.error || "Failed to create room");
6798
- }
6799
- const roomData = response.roomData || response;
6800
- const room = new VenusRoom(roomData);
6801
- return room;
6802
6512
  }
6803
- async joinOrCreateRoom(options) {
6513
+ async getSlotContainersAsync() {
6804
6514
  const response = await this.rpcClient.call(
6805
- "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
6515
+ "H5_SIMULATION_GET_CONTAINERS" /* H5_SIMULATION_GET_CONTAINERS */,
6516
+ {}
6517
+ );
6518
+ return response.containers || [];
6519
+ }
6520
+ async getSlotAssignmentsAsync(containerId) {
6521
+ const response = await this.rpcClient.call(
6522
+ "H5_SIMULATION_GET_ASSIGNMENTS" /* H5_SIMULATION_GET_ASSIGNMENTS */,
6806
6523
  {
6807
- options
6524
+ containerId
6808
6525
  }
6809
6526
  );
6810
- if (response.success === false) {
6811
- throw new Error(response.error || "Failed to join or create room");
6812
- }
6813
- const data = response.value || response;
6814
- const room = new VenusRoom(data.roomData);
6815
- return {
6816
- action: data.action,
6817
- room,
6818
- playersJoined: data.playersJoined
6819
- };
6527
+ return Array.isArray(response) ? response : response.assignments || [];
6820
6528
  }
6821
- async joinRoomByCode(roomCode) {
6529
+ async getStateAsync(roomId) {
6822
6530
  const response = await this.rpcClient.call(
6823
- "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
6531
+ "H5_SIMULATION_GET_STATE" /* H5_SIMULATION_GET_STATE */,
6824
6532
  {
6825
- roomCode
6533
+ roomId
6826
6534
  }
6827
6535
  );
6828
- if (response?.success === false) {
6829
- throw new Error(response.error || "Failed to join room by code");
6536
+ if (response.configuration) {
6537
+ this._simulationConfig = response.configuration;
6830
6538
  }
6831
- const roomData = response.roomData || response;
6832
- const room = new VenusRoom(roomData);
6833
- return room;
6539
+ return response;
6834
6540
  }
6835
- // Get user's rooms with optional filtering
6836
- async getUserRooms(includeArchived = false) {
6837
- const response = await this.rpcClient.call(
6838
- "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
6541
+ async getConfigAsync(roomId) {
6542
+ if (this._simulationConfig) {
6543
+ return this._simulationConfig;
6544
+ }
6545
+ const config = await this.rpcClient.call(
6546
+ "H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
6839
6547
  {
6840
- includeArchived
6548
+ roomId
6841
6549
  }
6842
6550
  );
6843
- if (response?.success === false) {
6844
- throw new Error(response.error || "Failed to get user rooms");
6551
+ if (config) {
6552
+ this._simulationConfig = config;
6553
+ return config;
6845
6554
  }
6846
- const rawRooms = response.rooms || [];
6847
- const venusRooms = [];
6848
- for (const roomData of rawRooms) {
6849
- if (!roomData.id) {
6850
- console.warn("getUserRooms: Skipping room with missing ID:", roomData);
6851
- continue;
6555
+ throw new Error("No simulation configuration available");
6556
+ }
6557
+ executeRecipeAsync(recipeId, inputs, options) {
6558
+ return this.rpcClient.call(
6559
+ "H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
6560
+ {
6561
+ recipeId,
6562
+ inputs,
6563
+ roomId: options?.roomId,
6564
+ batchAmount: options?.batchAmount,
6565
+ allowPartialBatch: options?.allowPartialBatch,
6566
+ entity: options?.entity
6852
6567
  }
6853
- try {
6854
- const venusRoom = new VenusRoom(roomData);
6855
- venusRooms.push(venusRoom);
6856
- } catch (error) {
6857
- console.warn(
6858
- "getUserRooms: Failed to create VenusRoom object:",
6859
- error,
6860
- roomData
6861
- );
6568
+ );
6569
+ }
6570
+ collectRecipeAsync(runId) {
6571
+ return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
6572
+ runId
6573
+ });
6574
+ }
6575
+ getActiveRunsAsync(options) {
6576
+ return this.rpcClient.call(
6577
+ "H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
6578
+ {
6579
+ roomId: options?.roomId
6862
6580
  }
6863
- }
6864
- return venusRooms;
6581
+ );
6865
6582
  }
6866
- async updateData(room, updates, merge = true) {
6867
- const response = await this.rpcClient.call(
6868
- "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
6583
+ executeScopedRecipeAsync(recipeId, entity, inputs, options) {
6584
+ return this.rpcClient.call(
6585
+ "H5_SIMULATION_EXECUTE_SCOPED_RECIPE" /* H5_SIMULATION_EXECUTE_SCOPED_RECIPE */,
6869
6586
  {
6870
- roomId: room.id,
6871
- updates,
6872
- merge
6587
+ recipeId,
6588
+ entity,
6589
+ inputs,
6590
+ roomId: options?.roomId ?? null,
6591
+ options
6873
6592
  }
6874
6593
  );
6875
- if (response?.success === false) {
6876
- throw new Error(response.error || "Failed to update room data");
6877
- }
6878
- return response.data;
6879
6594
  }
6880
- async getData(room) {
6881
- const response = await this.rpcClient.call(
6882
- "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
6595
+ getAvailableRecipesAsync(options) {
6596
+ return this.rpcClient.call(
6597
+ "H5_SIMULATION_GET_AVAILABLE_RECIPES" /* H5_SIMULATION_GET_AVAILABLE_RECIPES */,
6883
6598
  {
6884
- roomId: room.id
6599
+ roomId: options?.roomId || null,
6600
+ includeActorRecipes: options?.includeActorRecipes || false
6885
6601
  }
6886
6602
  );
6887
- if (response?.success === false) {
6888
- throw new Error(response.error || "Failed to get room data");
6889
- }
6890
- return response.data;
6891
6603
  }
6892
- async sendMessage(venusRoom, messageData) {
6893
- const response = await this.rpcClient.call(
6894
- "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
6604
+ getRecipeRequirementsAsync(recipe) {
6605
+ return this.rpcClient.call(
6606
+ "H5_SIMULATION_GET_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_RECIPE_REQUIREMENTS */,
6895
6607
  {
6896
- roomId: venusRoom.id,
6897
- message: messageData
6608
+ recipeId: recipe.recipeId,
6609
+ entity: recipe.entity,
6610
+ batchAmount: recipe.batchAmount
6898
6611
  }
6899
6612
  );
6900
- if (response?.success === false) {
6901
- throw new Error(response.error || "Failed to send message");
6902
- }
6903
- return response.messageId;
6904
6613
  }
6905
- async leave(room) {
6906
- const response = await this.rpcClient.call(
6907
- "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
6614
+ getBatchRecipeRequirementsAsync(recipes) {
6615
+ return this.rpcClient.call(
6616
+ "H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS */,
6908
6617
  {
6909
- roomId: room.id
6618
+ recipes
6910
6619
  }
6911
6620
  );
6912
- if (response?.success === false) {
6913
- throw new Error(response.error || "Failed to leave room");
6914
- }
6915
- return response;
6916
6621
  }
6917
- async startGame(room, gameConfig = {}, turnOrder = null) {
6918
- const response = await this.rpcClient.call(
6919
- "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
6622
+ triggerRecipeChainAsync(recipeId, options) {
6623
+ return this.rpcClient.call(
6624
+ "H5_SIMULATION_TRIGGER_RECIPE_CHAIN" /* H5_SIMULATION_TRIGGER_RECIPE_CHAIN */,
6920
6625
  {
6921
- roomId: room.id,
6922
- gameConfig,
6923
- turnOrder
6626
+ triggerRecipeId: recipeId,
6627
+ context: options?.context,
6628
+ roomId: options?.roomId
6924
6629
  }
6925
6630
  );
6926
- if (response?.success === false) {
6927
- throw new Error(response.error || "Failed to start game");
6928
- }
6929
- return response.data;
6930
6631
  }
6931
- async proposeMove(room, proposalPayload) {
6932
- const response = await this.rpcClient.call(
6933
- "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
6632
+ getEntityMetadataAsync(entityId) {
6633
+ return this.rpcClient.call(
6634
+ "H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
6934
6635
  {
6935
- roomId: room.id,
6936
- gameSpecificState: proposalPayload.gameSpecificState,
6937
- moveType: proposalPayload.moveType,
6938
- clientContext: proposalPayload.clientContext,
6939
- clientProposalId: proposalPayload.clientProposalId
6636
+ entityId
6940
6637
  }
6941
6638
  );
6942
- if (response?.success === false) {
6943
- throw new Error(response.error || "Failed to propose move");
6944
- }
6945
- return response.data;
6946
6639
  }
6947
- async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
6948
- console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
6949
- return { success: true, moveId, isValid, reason };
6640
+ async resolveFieldValueAsync(entityId, fieldPath, entity) {
6641
+ const response = await this.rpcClient.call(
6642
+ "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
6643
+ {
6644
+ entityId,
6645
+ fieldPath,
6646
+ entity
6647
+ }
6648
+ );
6649
+ return response.value;
6950
6650
  }
6951
- async roomSubscribeToGameEvents(room, callback) {
6952
- "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
6953
- if (!this.subscriptions.gameEvents[room.id]) {
6954
- this.subscriptions.gameEvents[room.id] = [];
6651
+ handleSimulationUpdate(notification) {
6652
+ if (!notification || !notification.subscriptionId) {
6653
+ console.warn("[Venus SDK] Received malformed simulation update");
6654
+ return;
6955
6655
  }
6956
- this.subscriptions.gameEvents[room.id].push(callback);
6957
- }
6958
- subscribe(room, options = {}) {
6959
- const subscriptionIds = [];
6960
- const roomId = room.id;
6961
- if (options.onData) {
6962
- const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
6963
- if (!this.subscriptions.data[roomId]) {
6964
- this.subscriptions.data[roomId] = [];
6965
- }
6966
- this.subscriptions.data[roomId].push(options.onData);
6967
- subscriptionIds.push({
6968
- type: "data",
6969
- id: dataSubId,
6970
- callback: options.onData
6971
- });
6656
+ const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
6657
+ if (!callback) {
6658
+ console.warn(
6659
+ "[Venus SDK] Received update for unknown subscription:",
6660
+ notification.subscriptionId
6661
+ );
6662
+ return;
6972
6663
  }
6973
- if (options.onMessages) {
6974
- const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
6975
- if (!this.subscriptions.messages[roomId]) {
6976
- this.subscriptions.messages[roomId] = [];
6977
- }
6978
- this.subscriptions.messages[roomId].push(options.onMessages);
6979
- subscriptionIds.push({
6980
- type: "messages",
6981
- id: msgSubId,
6982
- callback: options.onMessages
6983
- });
6664
+ try {
6665
+ callback(notification.updates);
6666
+ } catch (error) {
6667
+ console.error("[Venus SDK] Error in simulation subscription callback", error);
6984
6668
  }
6985
- if (options.onMoves || options.onGameEvents) {
6986
- const handler = options.onMoves || options.onGameEvents;
6987
- if (handler) {
6988
- const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
6989
- if (!this.subscriptions.gameEvents[roomId]) {
6990
- this.subscriptions.gameEvents[roomId] = [];
6991
- }
6992
- this.subscriptions.gameEvents[roomId].push(handler);
6993
- subscriptionIds.push({
6994
- type: "gameEvents",
6995
- id: gameSubId,
6996
- callback: handler
6997
- });
6998
- }
6669
+ }
6670
+ ensureValidSubscribeOptions(options) {
6671
+ if (typeof options !== "object" || options === null) {
6672
+ throw new Error("Simulation subscribe requires an options object");
6999
6673
  }
7000
- const needsSubscription = subscriptionIds.length > 0 && (this.subscriptions.data[roomId]?.length ?? 0) <= 1 && (this.subscriptions.messages[roomId]?.length ?? 0) <= 1 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) <= 1;
7001
- if (needsSubscription) {
7002
- this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
7003
- roomId,
7004
- subscribeToData: !!options.onData,
7005
- subscribeToMessages: !!options.onMessages,
7006
- subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
7007
- }).catch((error) => {
7008
- console.error("Failed to set up room subscription:", error);
7009
- });
6674
+ const opts = options;
6675
+ if (typeof opts.onUpdate !== "function") {
6676
+ throw new Error("Simulation subscribe requires an onUpdate callback");
6677
+ }
6678
+ const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
6679
+ if (!hasFilter) {
6680
+ throw new Error(
6681
+ "Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
6682
+ );
7010
6683
  }
7011
- let called = false;
7012
- return () => {
7013
- if (called) return;
7014
- called = true;
7015
- subscriptionIds.forEach((sub) => {
7016
- const bucket = this.subscriptions[sub.type];
7017
- const callbacks = bucket && bucket[roomId] || [];
7018
- const index = callbacks.indexOf(sub.callback);
7019
- if (index > -1) callbacks.splice(index, 1);
7020
- });
7021
- const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
7022
- if (hasNoCallbacks) {
7023
- this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
7024
- roomId
7025
- }).catch((error) => {
7026
- console.error("Failed to clean up room subscription:", error);
7027
- });
7028
- }
7029
- };
7030
6684
  }
7031
6685
  };
7032
6686
 
6687
+ // src/simulation/index.ts
6688
+ function initializeSimulation(venusApi, host) {
6689
+ venusApi.simulation = {
6690
+ isEnabled: () => true
6691
+ };
6692
+ venusApi.simulation.getConfigAsync = () => {
6693
+ return host.simulation.getConfigAsync();
6694
+ };
6695
+ venusApi.simulation.getStateAsync = (roomId) => {
6696
+ return host.simulation.getStateAsync(roomId);
6697
+ };
6698
+ venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
6699
+ return host.simulation.executeRecipeAsync(recipeId, inputs, options);
6700
+ };
6701
+ venusApi.simulation.getActiveRunsAsync = () => {
6702
+ return host.simulation.getActiveRunsAsync();
6703
+ };
6704
+ venusApi.simulation.collectRecipeAsync = (runId) => {
6705
+ return host.simulation.collectRecipeAsync(runId);
6706
+ };
6707
+ venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
6708
+ return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
6709
+ };
6710
+ venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
6711
+ return host.simulation.triggerRecipeChainAsync(recipeId, options);
6712
+ };
6713
+ venusApi.simulation.getAvailableRecipesAsync = async (options) => {
6714
+ return host.simulation.getAvailableRecipesAsync(options);
6715
+ };
6716
+ venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
6717
+ return host.simulation.getRecipeRequirementsAsync(recipe);
6718
+ };
6719
+ venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
6720
+ return host.simulation.getBatchRecipeRequirementsAsync(recipes);
6721
+ };
6722
+ venusApi.simulation.resolveFieldValueAsync = (entityId, fieldPath, entity) => {
6723
+ return host.simulation.resolveFieldValueAsync(entityId, fieldPath, entity);
6724
+ };
6725
+ venusApi.simulation.getEntityMetadataAsync = (entityId) => {
6726
+ return host.simulation.getEntityMetadataAsync(entityId);
6727
+ };
6728
+ venusApi.simulation.getSlotAssignmentsAsync = (containerId) => {
6729
+ return host.simulation.getSlotAssignmentsAsync(containerId);
6730
+ };
6731
+ venusApi.simulation.getSlotContainersAsync = () => {
6732
+ return host.simulation.getSlotContainersAsync();
6733
+ };
6734
+ venusApi.simulation.assignItemToSlotAsync = (containerId, slotId, itemId) => {
6735
+ return host.simulation.assignItemToSlotAsync(containerId, slotId, itemId);
6736
+ };
6737
+ venusApi.simulation.removeItemFromSlotAsync = (containerId, slotId) => {
6738
+ return host.simulation.removeItemFromSlotAsync(containerId, slotId);
6739
+ };
6740
+ venusApi.simulation.getAvailableItemsAsync = (containerId, slotId) => {
6741
+ return host.simulation.getAvailableItemsAsync(containerId, slotId);
6742
+ };
6743
+ venusApi.simulation.calculatePowerPreviewAsync = (containerId, slotId, candidateItemId) => {
6744
+ return host.simulation.calculatePowerPreviewAsync(
6745
+ containerId,
6746
+ slotId,
6747
+ candidateItemId
6748
+ );
6749
+ };
6750
+ venusApi.simulation.executeBatchOperationsAsync = (operations, validateOnly) => {
6751
+ return host.simulation.executeBatchOperationsAsync(operations, validateOnly);
6752
+ };
6753
+ venusApi.simulation.validateSlotAssignmentAsync = (containerId, slotId, itemId) => {
6754
+ return host.simulation.validateSlotAssignmentAsync(
6755
+ containerId,
6756
+ slotId,
6757
+ itemId
6758
+ );
6759
+ };
6760
+ }
6761
+
7033
6762
  // src/social/RpcSocialApi.ts
7034
6763
  var RpcSocialApi = class {
7035
6764
  constructor(rpcClient) {
@@ -7076,9 +6805,9 @@ var RemoteHost = class {
7076
6805
  __publicField(this, "notifications");
7077
6806
  __publicField(this, "popups");
7078
6807
  __publicField(this, "profile");
6808
+ __publicField(this, "system");
7079
6809
  __publicField(this, "cdn");
7080
6810
  __publicField(this, "time");
7081
- __publicField(this, "post");
7082
6811
  __publicField(this, "ai");
7083
6812
  __publicField(this, "haptics");
7084
6813
  __publicField(this, "features");
@@ -7132,10 +6861,12 @@ var RemoteHost = class {
7132
6861
  this.navigation = new RpcNavigationApi(rpcClient, venusApi);
7133
6862
  this.notifications = new RpcNotificationsApi(rpcClient);
7134
6863
  this.popups = new RpcPopupsApi(rpcClient);
7135
- this.profile = new HostProfileApi();
6864
+ this.profile = new HostProfileApi(venusApi);
6865
+ const deviceApi = new HostDeviceApi(venusApi);
6866
+ const environmentApi = new HostEnvironmentApi(venusApi);
6867
+ this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
7136
6868
  this.cdn = new HostCdnApi(getCdnBaseUrl());
7137
- this.time = new HostTimeApi(rpcClient);
7138
- this.post = new RpcPostApi(rpcClient);
6869
+ this.time = new HostTimeApi(rpcClient, venusApi);
7139
6870
  this.ai = new RpcAiApi(rpcClient);
7140
6871
  this.haptics = new RpcHapticsApi(rpcClient);
7141
6872
  this.features = new RpcFeaturesApi(rpcClient);
@@ -7150,7 +6881,6 @@ var RemoteHost = class {
7150
6881
  venusApi.isMock = () => false;
7151
6882
  this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
7152
6883
  initializeRoomsApi(this.venusApi, this);
7153
- console.log("[Venus SDK] Remote host created");
7154
6884
  }
7155
6885
  get isInitialized() {
7156
6886
  return this._isInitialized;
@@ -7168,36 +6898,28 @@ var RemoteHost = class {
7168
6898
  5e3
7169
6899
  );
7170
6900
  transport.instanceId = response.instanceId;
7171
- this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
7172
- if (response.profile) {
7173
- const profile = response.profile;
7174
- const sanitizedProfile = {
7175
- id: profile.id,
7176
- username: profile.username,
7177
- avatarUrl: profile.avatarUrl ?? null,
7178
- isAnonymous: Boolean(profile.isAnonymous)
7179
- };
7180
- if (typeof window !== "undefined") {
7181
- const globalWindow = window;
7182
- const venus = globalWindow.venus || (globalWindow.venus = {});
7183
- venus.profile = sanitizedProfile;
7184
- if (venus._config) {
7185
- venus._config.profile = sanitizedProfile;
7186
- }
7187
- if (venus.config) {
7188
- venus.config.profile = sanitizedProfile;
7189
- }
7190
- }
7191
- }
6901
+ this.log(`Remote Host Initialized with id: ${transport.instanceId}, response: ${JSON.stringify(response)}`);
6902
+ const profile = response.profile;
6903
+ const sanitizedProfile = {
6904
+ id: profile.id,
6905
+ username: profile.username,
6906
+ avatarUrl: profile.avatarUrl ?? null,
6907
+ isAnonymous: Boolean(profile.isAnonymous)
6908
+ };
6909
+ this.venusApi._profileData = sanitizedProfile;
6910
+ this.venusApi._deviceData = response.device;
6911
+ this.venusApi._environmentData = response.environment;
6912
+ this.venusApi._localeData = response.locale;
6913
+ this.venusApi._languageCodeData = response.languageCode;
7192
6914
  this._isInitialized = true;
7193
- this.venusApi.launchParams = response.launchParams || {};
6915
+ this.venusApi.launchParams = response.launchParams;
7194
6916
  await this.rpcClient.call("READY" /* READY */, {});
7195
- const hudInsets = response.hudInsets;
7196
- if (hudInsets) {
7197
- this.venusApi.config.ui.safeArea = hudInsets;
6917
+ const safeArea = response.safeArea;
6918
+ if (safeArea) {
6919
+ this.venusApi._safeAreaData = safeArea;
7198
6920
  }
7199
6921
  return {
7200
- hudInsets,
6922
+ safeArea,
7201
6923
  initializeAsleep: response.initializeAsleep
7202
6924
  };
7203
6925
  }
@@ -7209,19 +6931,14 @@ var RemoteHost = class {
7209
6931
  // src/Host.ts
7210
6932
  function createHost(venusApi, isMock) {
7211
6933
  if (isMock) {
7212
- console.log("[Venus SDK] Creating Local Host");
7213
6934
  return new MockHost(venusApi);
7214
6935
  } else {
7215
- console.log("[Venus SDK] Creating Remote Host");
7216
6936
  return new RemoteHost(venusApi);
7217
6937
  }
7218
6938
  }
7219
6939
 
7220
- // src/venus-api/index.js
7221
- init_rooms();
7222
-
7223
6940
  // src/version.ts
7224
- var SDK_VERSION = "3.0.4";
6941
+ var SDK_VERSION = "3.2.1-beta.0";
7225
6942
 
7226
6943
  // src/social/index.ts
7227
6944
  function initializeSocial(venusApi, host) {
@@ -7271,82 +6988,8 @@ var VenusAPI2 = class {
7271
6988
  bottom: 10,
7272
6989
  left: 0
7273
6990
  },
7274
- uiControls: {
7275
- closeButton: { x: 16, y: 16, width: 32, height: 32 },
7276
- menuButton: { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
7277
- feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 66 },
7278
- playButton: {
7279
- x: 0,
7280
- y: window.innerHeight - 60,
7281
- width: window.innerWidth,
7282
- height: 60
7283
- }
7284
- },
7285
- // Complete theme structure (matching createH5Theme output)
7286
- theme: {
7287
- background: {
7288
- default: "#131419",
7289
- muted: "#1b1d25",
7290
- dark: "#0d0e11"
7291
- },
7292
- text: {
7293
- primary: "#ffffff",
7294
- muted: "#808080",
7295
- inverted: "#000000"
7296
- },
7297
- theme: {
7298
- primary: "#f6c833",
7299
- secondary: "#6366f1",
7300
- background: "#131419",
7301
- border: "#262626",
7302
- card: "#1b1d25",
7303
- "card-glass": "rgba(27, 29, 37, 0.8)"
7304
- },
7305
- typography: {
7306
- fontFamily: {
7307
- base: "Plus Jakarta Sans, Roboto, sans-serif",
7308
- heading: "Plus Jakarta Sans, Roboto, sans-serif",
7309
- mono: "monospace"
7310
- },
7311
- fontSize: {
7312
- "2xs": "10px",
7313
- xs: "12px",
7314
- sm: "14px",
7315
- md: "16px",
7316
- lg: "18px",
7317
- xl: "20px",
7318
- "2xl": "24px",
7319
- "3xl": "30px",
7320
- "4xl": "36px",
7321
- "5xl": "48px",
7322
- "6xl": "60px"
7323
- },
7324
- fontWeight: {
7325
- thin: "100",
7326
- extralight: "200",
7327
- light: "300",
7328
- regular: "400",
7329
- medium: "500",
7330
- semibold: "600",
7331
- bold: "700",
7332
- extrabold: "800",
7333
- black: "900",
7334
- extrablack: "950"
7335
- },
7336
- lineHeight: {
7337
- none: "1",
7338
- tight: "1.25",
7339
- snug: "1.375",
7340
- normal: "1.5",
7341
- relaxed: "1.625",
7342
- loose: "2"
7343
- }
7344
- }
7345
- },
7346
- // Static locale data at top level
7347
- locale: "en-US",
7348
- languageCode: "en",
7349
- // Note: Profile is now separate from config and accessed via getCurrentProfile()
6991
+ // NOTE: locale and languageCode are NOT part of static config
6992
+ // They are delivered via INIT_SDK handshake and accessed via getLocale()/getLanguageCode()
7350
6993
  // Complete environment info (matching buildStaticConfig)
7351
6994
  environment: {
7352
6995
  isDevelopment: true,
@@ -7400,12 +7043,6 @@ var VenusAPI2 = class {
7400
7043
  onHide: null,
7401
7044
  onShow: null
7402
7045
  },
7403
- currentPostInteractions: {
7404
- isLiked: false,
7405
- isFollowing: false,
7406
- likesCount: 42,
7407
- commentsCount: 7
7408
- },
7409
7046
  // Platform overrides for testing different environments
7410
7047
  platformOverrides: {
7411
7048
  isMobile: true,
@@ -7414,117 +7051,74 @@ var VenusAPI2 = class {
7414
7051
  };
7415
7052
  this._detectHostedEnvironment();
7416
7053
  this.launchParams = {};
7417
- this.config = createProxiedObject.call(this, "config", {
7418
- locale: "en-US",
7419
- languageCode: "en",
7420
- // Note: Profile is no longer in config - use getCurrentProfile() instead
7421
- environment: {
7422
- isDevelopment: true,
7423
- platform: typeof navigator !== "undefined" ? navigator.platform : "unknown",
7424
- platformVersion: "unknown",
7425
- browserInfo: {
7426
- browser: "unknown",
7427
- userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "unknown",
7428
- isMobile: true,
7429
- isTablet: false,
7430
- language: typeof navigator !== "undefined" ? navigator.language : "en-US"
7054
+ this.config = createProxiedObject.call(this, "config", {});
7055
+ const originalConfig = this.config;
7056
+ this.config = new Proxy(originalConfig, {
7057
+ get(target, prop) {
7058
+ if (prop === "locale") {
7059
+ throw new Error("Use VenusAPI.getLocale() instead.");
7060
+ }
7061
+ if (prop === "languageCode") {
7062
+ throw new Error("Use VenusAPI.getLanguageCode() instead.");
7063
+ }
7064
+ if (prop === "user") {
7065
+ throw new Error("Use VenusAPI.getLocale() and VenusAPI.getLanguageCode() instead.");
7066
+ }
7067
+ if (prop === "device") {
7068
+ throw new Error("Use VenusAPI.system.getDevice() instead.");
7069
+ }
7070
+ if (prop === "environment") {
7071
+ throw new Error("Use VenusAPI.system.getEnvironment() instead.");
7072
+ }
7073
+ if (prop === "profile") {
7074
+ throw new Error("Use VenusAPI.getProfile() instead.");
7075
+ }
7076
+ if (prop === "rooms") {
7077
+ throw new Error("Rooms configuration is internal. Use VenusAPI.rooms methods instead.");
7078
+ }
7079
+ if (prop === "ui") {
7080
+ return new Proxy({}, {
7081
+ get(uiTarget, uiProp) {
7082
+ if (uiProp === "safeArea") {
7083
+ throw new Error("Use VenusAPI.system.getSafeArea() instead.");
7084
+ }
7085
+ if (uiProp === "hudInsets") {
7086
+ throw new Error("Use VenusAPI.system.getSafeArea() instead.");
7087
+ }
7088
+ if (uiProp === "controls") {
7089
+ throw new Error("UI controls are no longer supported.");
7090
+ }
7091
+ throw new Error(`VenusAPI.config.ui.${uiProp} is not supported.`);
7092
+ }
7093
+ });
7431
7094
  }
7095
+ return target[prop];
7432
7096
  },
7433
- ui: {
7434
- controls: {
7435
- closeButton: { x: 16, y: 16, width: 32, height: 32 },
7436
- menuButton: {
7437
- x: typeof window !== "undefined" ? window.innerWidth - 48 : 352,
7438
- y: 16,
7439
- width: 32,
7440
- height: 32
7441
- },
7442
- feedHeader: {
7443
- x: 0,
7444
- y: 0,
7445
- width: typeof window !== "undefined" ? window.innerWidth : 400,
7446
- height: 66
7447
- },
7448
- playButton: {
7449
- x: 0,
7450
- y: typeof window !== "undefined" ? window.innerHeight - 60 : 740,
7451
- width: typeof window !== "undefined" ? window.innerWidth : 400,
7452
- height: 60
7453
- }
7454
- },
7455
- safeArea: { top: 44, left: 0, right: 0, bottom: 34 },
7456
- hudInsets: {
7457
- preview: { top: 60, left: 0, right: 0, bottom: 40 },
7458
- fullscreen: { top: 44, left: 0, right: 0, bottom: 34 }
7097
+ set(target, prop, value) {
7098
+ if (prop === "locale" || prop === "languageCode" || prop === "user" || prop === "device" || prop === "environment" || prop === "profile") {
7099
+ throw new Error(`VenusAPI.config.${prop} cannot be set. Configuration is read-only.`);
7100
+ }
7101
+ if (prop === "ui") {
7102
+ console.warn("[Venus SDK] Cannot set config.ui");
7103
+ return true;
7459
7104
  }
7105
+ target[prop] = value;
7106
+ return true;
7460
7107
  },
7461
- device: {
7462
- screenSize: {
7463
- width: typeof window !== "undefined" ? window.screen?.width || 0 : 0,
7464
- height: typeof window !== "undefined" ? window.screen?.height || 0 : 0
7465
- },
7466
- viewportSize: {
7467
- width: typeof window !== "undefined" ? window.innerWidth : 0,
7468
- height: typeof window !== "undefined" ? window.innerHeight : 0
7469
- },
7470
- orientation: "portrait",
7471
- pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
7472
- fontScale: 1,
7473
- deviceType: "phone",
7474
- hapticsEnabled: false,
7475
- haptics: { supported: false, enabled: false }
7108
+ has(target, prop) {
7109
+ if (prop === "ui") {
7110
+ return false;
7111
+ }
7112
+ return prop in target;
7476
7113
  },
7477
- theme: {
7478
- background: { default: "#131419", muted: "#1b1d25", dark: "#0d0e11" },
7479
- text: { primary: "#ffffff", muted: "#808080", inverted: "#000000" },
7480
- theme: {
7481
- primary: "#f6c833",
7482
- secondary: "#6366f1",
7483
- background: "#131419",
7484
- border: "#262626",
7485
- card: "#1b1d25",
7486
- "card-glass": "rgba(27, 29, 37, 0.8)"
7487
- },
7488
- typography: {
7489
- fontFamily: {
7490
- base: "Plus Jakarta Sans, Roboto, sans-serif",
7491
- heading: "Plus Jakarta Sans, Roboto, sans-serif",
7492
- mono: "monospace"
7493
- },
7494
- fontSize: {
7495
- "2xs": "10px",
7496
- xs: "12px",
7497
- sm: "14px",
7498
- md: "16px",
7499
- lg: "18px",
7500
- xl: "20px",
7501
- "2xl": "24px",
7502
- "3xl": "30px",
7503
- "4xl": "36px",
7504
- "5xl": "48px",
7505
- "6xl": "60px"
7506
- },
7507
- fontWeight: {
7508
- thin: "100",
7509
- extralight: "200",
7510
- light: "300",
7511
- regular: "400",
7512
- medium: "500",
7513
- semibold: "600",
7514
- bold: "700",
7515
- extrabold: "800",
7516
- black: "900",
7517
- extrablack: "950"
7518
- },
7519
- lineHeight: {
7520
- none: "1",
7521
- tight: "1.25",
7522
- snug: "1.375",
7523
- normal: "1.5",
7524
- relaxed: "1.625",
7525
- loose: "2"
7526
- }
7114
+ ownKeys(target) {
7115
+ return Reflect.ownKeys(target).filter((key) => key !== "ui");
7116
+ },
7117
+ getOwnPropertyDescriptor(target, prop) {
7118
+ if (prop === "ui") {
7119
+ return void 0;
7527
7120
  }
7121
+ return Reflect.getOwnPropertyDescriptor(target, prop);
7528
7122
  }
7529
7123
  });
7530
7124
  const isInsideHostedEnv = this._bootstrap.isInsideHostedEnvironment;
@@ -7533,7 +7127,6 @@ var VenusAPI2 = class {
7533
7127
  initializeStorage(this, host);
7534
7128
  initializeRoomsApi(this, host);
7535
7129
  initializeAds(this, host);
7536
- initializeTheme(this);
7537
7130
  initializePopups(this, host);
7538
7131
  initializeAnalytics(this, host);
7539
7132
  initializeIap(this, host);
@@ -7548,15 +7141,31 @@ var VenusAPI2 = class {
7548
7141
  initializeLoggingApi(this, host);
7549
7142
  const isAvatar3dDisabled = typeof window !== "undefined" && window.location.search.includes("EXPO_PUBLIC_DISABLE_3D_AVATARS=true");
7550
7143
  initializeProfile(this, host);
7144
+ initializeSystem(this, host);
7551
7145
  if (!isAvatar3dDisabled) {
7552
7146
  initializeAvatar3d(this, host);
7553
7147
  }
7554
7148
  initializeStackNavigation(this, host);
7555
- initializePost(this, host);
7556
7149
  initializeAi(this, host);
7557
7150
  initializeSimulation(this, host);
7558
7151
  initializeSocial(this, host);
7559
7152
  initializeAssetLoader(this, createProxiedMethod);
7153
+ this.getLocale = () => {
7154
+ if (this._localeData) {
7155
+ return this._localeData;
7156
+ }
7157
+ if (typeof navigator !== "undefined" && navigator.language) {
7158
+ return navigator.language;
7159
+ }
7160
+ return "en-US";
7161
+ };
7162
+ this.getLanguageCode = () => {
7163
+ if (this._languageCodeData) {
7164
+ return this._languageCodeData;
7165
+ }
7166
+ const locale = this.getLocale();
7167
+ return locale.split("-")[0];
7168
+ };
7560
7169
  }
7561
7170
  // Generate deterministic instance ID based on current page URL
7562
7171
  _generateDeterministicInstanceId() {
@@ -7593,21 +7202,14 @@ var VenusAPI2 = class {
7593
7202
  // BOOTSTRAP METHODS
7594
7203
  //---------------------------------------
7595
7204
  _detectHostedEnvironment() {
7596
- console.log("[Venus SDK] Detecting host environment...");
7597
7205
  const isInIframe = window.self !== window.top;
7598
7206
  const hasReactNativeWebView = typeof window.ReactNativeWebView !== "undefined";
7599
7207
  this._bootstrap.isInsideHostedEnvironment = isInIframe || hasReactNativeWebView;
7600
- console.log(
7601
- `[Venus SDK] isInIframe: ${isInIframe}, hasReactNativeWebView: ${hasReactNativeWebView}`
7602
- );
7603
- }
7604
- isMobile() {
7605
- return typeof window.ReactNativeWebView !== "undefined";
7606
7208
  }
7607
7209
  _initializeMockMode() {
7608
7210
  if (this._mock.localeOverride) {
7609
- this.config.locale = this._mock.localeOverride;
7610
- this.config.languageCode = this._mock.localeOverride.split("-")[0];
7211
+ this._localeData = this._mock.localeOverride;
7212
+ this._languageCodeData = this._mock.localeOverride.split("-")[0];
7611
7213
  }
7612
7214
  if (this._mock.roomsData) {
7613
7215
  console.warn(
@@ -7627,6 +7229,10 @@ var VenusAPI2 = class {
7627
7229
  }
7628
7230
  this._shared.initPromise = new Promise(async (resolve, reject) => {
7629
7231
  try {
7232
+ if (this.isMock() && options?.mock) {
7233
+ Object.assign(this._mock, options.mock);
7234
+ console.log("[VenusAPI] Mock options applied:", options.mock);
7235
+ }
7630
7236
  const result = await this.host.initialize(options);
7631
7237
  this._shared.initialized = true;
7632
7238
  if (!options || !options.usePreloader) {
@@ -7654,7 +7260,6 @@ instance.isAvailable = function() {
7654
7260
  (async () => {
7655
7261
  try {
7656
7262
  await initializeNumbers(instance);
7657
- console.log("[Venus SDK] Numbers system initialized");
7658
7263
  } catch (error) {
7659
7264
  console.error("[Venus SDK] Failed to initialize numbers system:", error);
7660
7265
  }