@series-inc/venus-sdk 3.1.2-beta.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{AdsApi-DFutZ7_q.d.mts → AdsApi-CNGRf6j0.d.mts} +293 -501
  2. package/dist/{AdsApi-DFutZ7_q.d.ts → AdsApi-CNGRf6j0.d.ts} +293 -501
  3. package/dist/{chunk-U6NFOU3E.mjs → chunk-PXWCNWJ6.mjs} +1525 -1380
  4. package/dist/chunk-PXWCNWJ6.mjs.map +1 -0
  5. package/dist/{chunk-QABXMFND.mjs → chunk-W7IPHM67.mjs} +26 -3
  6. package/dist/chunk-W7IPHM67.mjs.map +1 -0
  7. package/dist/core-R3FHW62G.mjs +3 -0
  8. package/dist/{core-62LWDHN7.mjs.map → core-R3FHW62G.mjs.map} +1 -1
  9. package/dist/index.cjs +1531 -1406
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.mts +92 -280
  12. package/dist/index.d.ts +92 -280
  13. package/dist/index.mjs +6 -4
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/venus-api/index.cjs +2012 -1548
  16. package/dist/venus-api/index.cjs.map +1 -1
  17. package/dist/venus-api/index.d.mts +2 -2
  18. package/dist/venus-api/index.d.ts +2 -2
  19. package/dist/venus-api/index.mjs +391 -92
  20. package/dist/venus-api/index.mjs.map +1 -1
  21. package/package.json +1 -1
  22. package/dist/chunk-NSSMTXJJ.mjs +0 -7
  23. package/dist/chunk-NSSMTXJJ.mjs.map +0 -1
  24. package/dist/chunk-QABXMFND.mjs.map +0 -1
  25. package/dist/chunk-U6NFOU3E.mjs.map +0 -1
  26. package/dist/chunk-UXY5CKKG.mjs +0 -12
  27. package/dist/chunk-UXY5CKKG.mjs.map +0 -1
  28. package/dist/core-62LWDHN7.mjs +0 -4
  29. package/dist/vite/index.cjs +0 -534
  30. package/dist/vite/index.cjs.map +0 -1
  31. package/dist/vite/index.mjs +0 -527
  32. package/dist/vite/index.mjs.map +0 -1
  33. package/dist/webview/index.cjs +0 -15
  34. package/dist/webview/index.cjs.map +0 -1
  35. package/dist/webview/index.d.mts +0 -15
  36. package/dist/webview/index.d.ts +0 -15
  37. package/dist/webview/index.mjs +0 -4
  38. package/dist/webview/index.mjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,9 +1,243 @@
1
1
  'use strict';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
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);
5
24
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
25
 
26
+ // src/rooms/RoomsApi.ts
27
+ var init_RoomsApi = __esm({
28
+ "src/rooms/RoomsApi.ts"() {
29
+ }
30
+ });
31
+
32
+ // src/rooms/VenusRoom.ts
33
+ exports.VenusRoom = void 0;
34
+ var init_VenusRoom = __esm({
35
+ "src/rooms/VenusRoom.ts"() {
36
+ exports.VenusRoom = class {
37
+ constructor(roomData) {
38
+ __publicField(this, "id");
39
+ __publicField(this, "name");
40
+ __publicField(this, "players");
41
+ __publicField(this, "maxPlayers");
42
+ __publicField(this, "gameType");
43
+ __publicField(this, "appId");
44
+ __publicField(this, "type");
45
+ __publicField(this, "createdBy");
46
+ __publicField(this, "createdAt");
47
+ __publicField(this, "updatedAt");
48
+ __publicField(this, "isPrivate");
49
+ __publicField(this, "currentPlayers");
50
+ __publicField(this, "status");
51
+ __publicField(this, "customMetadata");
52
+ __publicField(this, "admins");
53
+ __publicField(this, "roomCode");
54
+ __publicField(this, "description");
55
+ __publicField(this, "data");
56
+ __publicField(this, "version");
57
+ __publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
58
+ this.id = roomData.id;
59
+ this.name = roomData.name;
60
+ this.players = roomData.currentPlayers || [];
61
+ this.maxPlayers = roomData.maxPlayers;
62
+ this.gameType = roomData.gameType;
63
+ this.appId = roomData.appId;
64
+ this.type = roomData.type;
65
+ this.createdBy = roomData.createdBy;
66
+ this.createdAt = roomData.createdAt;
67
+ this.updatedAt = roomData.updatedAt;
68
+ this.isPrivate = roomData.isPrivate;
69
+ this.currentPlayers = roomData.currentPlayers || [];
70
+ this.status = roomData.status;
71
+ this.customMetadata = roomData.customMetadata || {};
72
+ this.admins = roomData.admins || [];
73
+ this.roomCode = roomData.roomCode;
74
+ this.description = roomData.description;
75
+ this.data = roomData.data || {};
76
+ this.version = roomData.version;
77
+ console.log(`VenusRoom: Created room object for ${this.id}`, {
78
+ hasCustomMetadata: !!this.customMetadata,
79
+ hasGameState: !!this.customMetadata?.rules?.gameState,
80
+ gamePhase: this.customMetadata?.rules?.gameState?.phase,
81
+ currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
82
+ });
83
+ }
84
+ updateFromRoomData(newRoomData) {
85
+ if (newRoomData.id === this.id) {
86
+ this.name = newRoomData.name || this.name;
87
+ this.players = newRoomData.currentPlayers || this.players;
88
+ this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
89
+ this.gameType = newRoomData.gameType || this.gameType;
90
+ this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
91
+ this.customMetadata = newRoomData.customMetadata || this.customMetadata;
92
+ this.data = newRoomData.data || this.data;
93
+ this.status = newRoomData.status || this.status;
94
+ this.updatedAt = newRoomData.updatedAt || this.updatedAt;
95
+ console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
96
+ hasCustomMetadata: !!this.customMetadata,
97
+ hasGameState: !!this.customMetadata?.rules?.gameState,
98
+ gamePhase: this.customMetadata?.rules?.gameState?.phase,
99
+ currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
100
+ });
101
+ }
102
+ }
103
+ };
104
+ }
105
+ });
106
+
107
+ // src/rooms/index.ts
108
+ var rooms_exports = {};
109
+ __export(rooms_exports, {
110
+ VenusRoom: () => exports.VenusRoom,
111
+ initializeRoomsApi: () => initializeRoomsApi,
112
+ setupRoomNotifications: () => setupRoomNotifications
113
+ });
114
+ function bindMethod(target, targetKey, source, sourceKey) {
115
+ const key = sourceKey ?? targetKey;
116
+ const fn = source?.[key];
117
+ if (typeof fn === "function") {
118
+ target[targetKey] = fn.bind(source);
119
+ return true;
120
+ }
121
+ return false;
122
+ }
123
+ function setupRoomNotifications(transport, getSubscriptions) {
124
+ console.log("[Venus Rooms] Setting up room notification listeners");
125
+ return transport.onVenusMessage((message) => {
126
+ const subscriptions = getSubscriptions();
127
+ if (!subscriptions) {
128
+ return;
129
+ }
130
+ if (message.type === "H5_ROOM_DATA_UPDATED") {
131
+ const messageData = message.data;
132
+ const { roomId, roomData } = messageData;
133
+ if (!roomId) return;
134
+ const callbacks = subscriptions.data?.[roomId] || [];
135
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
136
+ console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
137
+ callbacks.forEach((callback) => {
138
+ try {
139
+ callback(roomData);
140
+ } catch (error) {
141
+ console.error("[Venus Rooms] Error in room data callback:", error);
142
+ throw error;
143
+ }
144
+ });
145
+ allEventsCallbacks.forEach((callback) => {
146
+ try {
147
+ callback({ type: message.type, ...messageData });
148
+ } catch (error) {
149
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
150
+ throw error;
151
+ }
152
+ });
153
+ }
154
+ if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
155
+ const messageData = message.data;
156
+ const { roomId } = messageData;
157
+ if (!roomId) return;
158
+ const callbacks = subscriptions.messages?.[roomId] || [];
159
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
160
+ console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
161
+ callbacks.forEach((callback) => {
162
+ try {
163
+ callback(messageData);
164
+ } catch (error) {
165
+ console.error("[Venus Rooms] Error in room message callback:", error);
166
+ throw error;
167
+ }
168
+ });
169
+ allEventsCallbacks.forEach((callback) => {
170
+ try {
171
+ callback({ type: message.type, ...messageData });
172
+ } catch (error) {
173
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
174
+ throw error;
175
+ }
176
+ });
177
+ }
178
+ if (message.type === "app:h5:proposedMoveValidationUpdated") {
179
+ const messageData = message.data;
180
+ const { roomId } = messageData;
181
+ if (!roomId) return;
182
+ const callbacks = subscriptions.gameEvents?.[roomId] || [];
183
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
184
+ console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
185
+ callbacks.forEach((callback) => {
186
+ try {
187
+ callback(messageData);
188
+ } catch (error) {
189
+ console.error("[Venus Rooms] Error in game event callback:", error);
190
+ throw error;
191
+ }
192
+ });
193
+ allEventsCallbacks.forEach((callback) => {
194
+ try {
195
+ callback({ type: message.type, ...messageData });
196
+ } catch (error) {
197
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
198
+ throw error;
199
+ }
200
+ });
201
+ }
202
+ });
203
+ }
204
+ function initializeRoomsApi(venusApi, host) {
205
+ const roomsApi = host?.rooms;
206
+ if (!roomsApi) {
207
+ console.warn(
208
+ "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
209
+ );
210
+ return;
211
+ }
212
+ const venus = venusApi;
213
+ const existingNamespace = venus.rooms || {};
214
+ const roomsNamespace = Object.assign({}, existingNamespace);
215
+ const namespaceBindings = [
216
+ ["create", "createRoom"],
217
+ ["joinOrCreate", "joinOrCreateRoom"],
218
+ ["joinByCode", "joinRoomByCode"],
219
+ ["list", "getUserRooms"],
220
+ ["subscribeToRoom", "subscribe"],
221
+ ["updateRoomData", "updateData"],
222
+ ["getRoomData", "getData"],
223
+ ["sendRoomMessage", "sendMessage"],
224
+ ["leaveRoom", "leave"],
225
+ ["startRoomGame", "startGame"],
226
+ ["proposeMove"],
227
+ ["validateMove"]
228
+ ];
229
+ namespaceBindings.forEach(([targetKey, sourceKey]) => {
230
+ bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
231
+ });
232
+ venus.rooms = roomsNamespace;
233
+ }
234
+ var init_rooms = __esm({
235
+ "src/rooms/index.ts"() {
236
+ init_RoomsApi();
237
+ init_VenusRoom();
238
+ }
239
+ });
240
+
7
241
  // src/VenusMessageId.ts
8
242
  var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
9
243
  VenusMessageId2["H5_RESPONSE"] = "H5_RESPONSE";
@@ -50,6 +284,10 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
50
284
  VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
51
285
  VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
52
286
  VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
287
+ VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
288
+ VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
289
+ VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
290
+ VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
53
291
  VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
54
292
  VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
55
293
  VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
@@ -91,14 +329,11 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
91
329
  VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
92
330
  VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
93
331
  VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
94
- VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
95
- VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
96
- VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
97
- VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
332
+ VenusMessageId2["H5_LEADERBOARD_START_RUN"] = "H5_LEADERBOARD_START_RUN";
98
333
  VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
99
- VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
100
- VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
101
- VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
334
+ VenusMessageId2["H5_LEADERBOARD_GET"] = "H5_LEADERBOARD_GET";
335
+ VenusMessageId2["H5_LEADERBOARD_GET_HIGHLIGHT"] = "H5_LEADERBOARD_GET_HIGHLIGHT";
336
+ VenusMessageId2["H5_LEADERBOARD_GET_PLAYER_STATS"] = "H5_LEADERBOARD_GET_PLAYER_STATS";
102
337
  VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
103
338
  VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
104
339
  VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
@@ -353,7 +588,7 @@ var MockAvatarApi = class {
353
588
  async deleteAvatar() {
354
589
  console.log(`[Venus Mock] Deleting avatar3d config`);
355
590
  const venusApi = this._venusApi;
356
- const currentProfile = venusApi.getProfile();
591
+ const currentProfile = venusApi.getCurrentProfile();
357
592
  const profileId = currentProfile?.id || "default_profile";
358
593
  localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
359
594
  console.log(
@@ -368,7 +603,7 @@ var MockAvatarApi = class {
368
603
  console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
369
604
  config = await this.selectAvatarConfig(avatar3dId, false);
370
605
  } else {
371
- const currentProfile = venusApi.getProfile();
606
+ const currentProfile = venusApi.getCurrentProfile();
372
607
  const profileId = currentProfile?.id || "default_profile";
373
608
  console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
374
609
  console.log(
@@ -385,7 +620,7 @@ var MockAvatarApi = class {
385
620
  async saveAvatar(config) {
386
621
  console.log(`[Venus Mock] Saving avatar3d config:`, config);
387
622
  const venusApi = this._venusApi;
388
- const currentProfile = venusApi.getProfile();
623
+ const currentProfile = venusApi.getCurrentProfile();
389
624
  const profileId = currentProfile?.id || "default_profile";
390
625
  localStorage.setItem(
391
626
  `venus-mock-avatar3d-${profileId}`,
@@ -916,15 +1151,9 @@ var HostCdnApi = class {
916
1151
 
917
1152
  // src/cdn/MockCdnApi.ts
918
1153
  var MockCdnApi = class {
919
- constructor(venusApi) {
920
- __publicField(this, "venusApi");
921
- this.venusApi = venusApi;
922
- }
923
- get baseUrl() {
924
- return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
925
- }
926
- get forceRemoteCdn() {
927
- return this.venusApi._mock?.cdnForceRemote ?? false;
1154
+ constructor() {
1155
+ __publicField(this, "baseUrl");
1156
+ this.baseUrl = "https://venus-static-01293ak.web.app/";
928
1157
  }
929
1158
  async fetchBlob(path, options) {
930
1159
  const controller = new AbortController();
@@ -961,10 +1190,6 @@ var MockCdnApi = class {
961
1190
  return subPath;
962
1191
  }
963
1192
  const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
964
- const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
965
- if (isLocalhost && !this.forceRemoteCdn) {
966
- return `/${cleanSubPath}`;
967
- }
968
1193
  const pathParts = cleanSubPath.split("/");
969
1194
  const encodedParts = pathParts.map((part, index) => {
970
1195
  return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
@@ -1086,212 +1311,6 @@ function initializeCdn(venusApi, host) {
1086
1311
  venusApi.cdn = host.cdn;
1087
1312
  }
1088
1313
 
1089
- // src/device/HostDeviceApi.ts
1090
- var HostDeviceApi = class {
1091
- constructor(venusApi) {
1092
- __publicField(this, "venusApi");
1093
- this.venusApi = venusApi;
1094
- }
1095
- getDevice() {
1096
- const device = this.venusApi._deviceData;
1097
- if (!device) {
1098
- throw new Error(
1099
- "[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
1100
- );
1101
- }
1102
- return device;
1103
- }
1104
- };
1105
-
1106
- // src/device/MockDeviceApi.ts
1107
- var MockDeviceApi = class {
1108
- constructor(venusApi) {
1109
- __publicField(this, "venusApi");
1110
- this.venusApi = venusApi;
1111
- }
1112
- getDevice() {
1113
- const width = typeof window !== "undefined" ? window.innerWidth : 400;
1114
- const height = typeof window !== "undefined" ? window.innerHeight : 800;
1115
- return {
1116
- screenSize: { width, height },
1117
- viewportSize: {
1118
- width: width - 20,
1119
- // account for safe area
1120
- height: height - 20
1121
- },
1122
- orientation: width > height ? "landscape" : "portrait",
1123
- pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
1124
- fontScale: 1,
1125
- deviceType: width > 768 ? "tablet" : "phone",
1126
- hapticsEnabled: false,
1127
- haptics: { supported: false, enabled: false }
1128
- };
1129
- }
1130
- };
1131
-
1132
- // src/environment/HostEnvironmentApi.ts
1133
- var HostEnvironmentApi = class {
1134
- constructor(venusApi) {
1135
- __publicField(this, "venusApi");
1136
- this.venusApi = venusApi;
1137
- }
1138
- getEnvironment() {
1139
- const environment = this.venusApi._environmentData;
1140
- if (!environment) {
1141
- throw new Error(
1142
- "[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
1143
- );
1144
- }
1145
- return environment;
1146
- }
1147
- };
1148
-
1149
- // src/environment/MockEnvironmentApi.ts
1150
- var MockEnvironmentApi = class {
1151
- constructor(venusApi) {
1152
- __publicField(this, "venusApi");
1153
- this.venusApi = venusApi;
1154
- }
1155
- getEnvironment() {
1156
- const getBrowser = () => {
1157
- if (typeof navigator === "undefined") return "unknown";
1158
- const userAgent = navigator.userAgent;
1159
- if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
1160
- if (/firefox|fxios/i.test(userAgent)) return "firefox";
1161
- if (/safari/i.test(userAgent)) return "safari";
1162
- if (/edg/i.test(userAgent)) return "edge";
1163
- if (/opera|opr/i.test(userAgent)) return "opera";
1164
- return "unknown";
1165
- };
1166
- return {
1167
- isDevelopment: true,
1168
- platform: "web",
1169
- platformVersion: "mock-1.0",
1170
- browserInfo: {
1171
- browser: getBrowser(),
1172
- userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
1173
- isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
1174
- isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
1175
- language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
1176
- }
1177
- };
1178
- }
1179
- };
1180
-
1181
- // src/system/HostSystemApi.ts
1182
- var HostSystemApi = class {
1183
- constructor(deviceApi, environmentApi, venusApi) {
1184
- __publicField(this, "deviceApi");
1185
- __publicField(this, "environmentApi");
1186
- __publicField(this, "venusApi");
1187
- this.deviceApi = deviceApi;
1188
- this.environmentApi = environmentApi;
1189
- this.venusApi = venusApi;
1190
- }
1191
- getDevice() {
1192
- return this.deviceApi.getDevice();
1193
- }
1194
- getEnvironment() {
1195
- return this.environmentApi.getEnvironment();
1196
- }
1197
- getSafeArea() {
1198
- const safeArea = this.venusApi._safeAreaData;
1199
- if (!safeArea) {
1200
- throw new Error(
1201
- "[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
1202
- );
1203
- }
1204
- return { ...safeArea };
1205
- }
1206
- isMobile() {
1207
- const environment = this.environmentApi.getEnvironment();
1208
- if (environment.platform === "ios" || environment.platform === "android") {
1209
- return true;
1210
- }
1211
- if (environment.browserInfo) {
1212
- return environment.browserInfo.isMobile;
1213
- }
1214
- return true;
1215
- }
1216
- isWeb() {
1217
- const environment = this.environmentApi.getEnvironment();
1218
- if (environment.platform === "web") {
1219
- return true;
1220
- }
1221
- if (environment.browserInfo && !environment.browserInfo.isMobile) {
1222
- return true;
1223
- }
1224
- return false;
1225
- }
1226
- };
1227
-
1228
- // src/system/MockSystemApi.ts
1229
- var MockSystemApi = class {
1230
- constructor(deviceApi, environmentApi, venusApi) {
1231
- __publicField(this, "deviceApi");
1232
- __publicField(this, "environmentApi");
1233
- __publicField(this, "venusApi");
1234
- this.deviceApi = deviceApi;
1235
- this.environmentApi = environmentApi;
1236
- this.venusApi = venusApi;
1237
- }
1238
- getDevice() {
1239
- return this.deviceApi.getDevice();
1240
- }
1241
- getEnvironment() {
1242
- return this.environmentApi.getEnvironment();
1243
- }
1244
- getSafeArea() {
1245
- const safeArea = this.venusApi._safeAreaData;
1246
- if (!safeArea) {
1247
- return {
1248
- top: 0,
1249
- right: 0,
1250
- bottom: 34,
1251
- left: 0
1252
- };
1253
- }
1254
- return { ...safeArea };
1255
- }
1256
- isMobile() {
1257
- const environment = this.environmentApi.getEnvironment();
1258
- if (environment.platform === "ios" || environment.platform === "android") {
1259
- return true;
1260
- }
1261
- if (environment.browserInfo) {
1262
- return environment.browserInfo.isMobile;
1263
- }
1264
- return true;
1265
- }
1266
- isWeb() {
1267
- const environment = this.environmentApi.getEnvironment();
1268
- if (environment.platform === "web") {
1269
- return true;
1270
- }
1271
- if (environment.browserInfo && !environment.browserInfo.isMobile) {
1272
- return true;
1273
- }
1274
- return false;
1275
- }
1276
- };
1277
-
1278
- // src/system/index.ts
1279
- function initializeSystem(venusApi, host) {
1280
- venusApi.system = host.system;
1281
- venusApi.isMobile = () => {
1282
- console.warn(
1283
- "[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
1284
- );
1285
- return host.system.isMobile();
1286
- };
1287
- venusApi.isWeb = () => {
1288
- console.warn(
1289
- "[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
1290
- );
1291
- return host.system.isWeb();
1292
- };
1293
- }
1294
-
1295
1314
  // src/features/RpcFeaturesApi.ts
1296
1315
  var RpcFeaturesApi = class {
1297
1316
  constructor(rcpClient) {
@@ -1774,8 +1793,13 @@ var MockNotificationsApi = class {
1774
1793
  async cancelNotification(notificationId) {
1775
1794
  const venusApi = this.venusApi;
1776
1795
  if (isWebPlatform()) {
1796
+ console.log(
1797
+ "[Venus Mock] Cancel notification on web platform (simulated):",
1798
+ notificationId
1799
+ );
1777
1800
  return true;
1778
1801
  }
1802
+ console.log("[Venus Mock] Cancel local notification:", notificationId);
1779
1803
  await createMockDelay(MOCK_DELAYS.short);
1780
1804
  if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
1781
1805
  delete venusApi._mock.scheduledNotifications[notificationId];
@@ -1785,8 +1809,12 @@ var MockNotificationsApi = class {
1785
1809
  }
1786
1810
  async getAllScheduledLocalNotifications() {
1787
1811
  if (isWebPlatform()) {
1812
+ console.log(
1813
+ "[Venus Mock] Get notifications on web platform (returning empty list)"
1814
+ );
1788
1815
  return [];
1789
1816
  }
1817
+ console.log("[Venus Mock] Get all scheduled local notifications");
1790
1818
  await createMockDelay(MOCK_DELAYS.short);
1791
1819
  const venusApi = this.venusApi;
1792
1820
  const notifications = venusApi._mock.scheduledNotifications || {};
@@ -1794,8 +1822,10 @@ var MockNotificationsApi = class {
1794
1822
  }
1795
1823
  async isLocalNotificationsEnabled() {
1796
1824
  if (isWebPlatform()) {
1825
+ console.log("[Venus Mock] Notifications not available on web platform");
1797
1826
  return false;
1798
1827
  }
1828
+ console.log("[Venus Mock] Check if local notifications are enabled");
1799
1829
  await createMockDelay(MOCK_DELAYS.short);
1800
1830
  const venusApi = this.venusApi;
1801
1831
  const isEnabled = venusApi._mock.notificationsEnabled !== false;
@@ -1804,6 +1834,9 @@ var MockNotificationsApi = class {
1804
1834
  async scheduleAsync(title, body, seconds, notificationId, options) {
1805
1835
  const { priority = 50, groupId, payload } = options || {};
1806
1836
  if (isWebPlatform()) {
1837
+ console.log(
1838
+ "[Venus Mock] Notifications not supported on web platform, simulating success"
1839
+ );
1807
1840
  console.info(
1808
1841
  "\u{1F514} [Venus Mock] Notification would be scheduled:",
1809
1842
  title || "Untitled",
@@ -1814,11 +1847,14 @@ var MockNotificationsApi = class {
1814
1847
  const mockId = `mock-web-notification-${Date.now()}`;
1815
1848
  return mockId;
1816
1849
  }
1850
+ console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
1817
1851
  const venusApi = this.venusApi;
1818
1852
  if (!venusApi._mock.pendingRequests) {
1853
+ console.log("[Venus Mock] Initializing pendingRequests");
1819
1854
  venusApi._mock.pendingRequests = {};
1820
1855
  }
1821
1856
  const requestId = Date.now().toString();
1857
+ console.log("[Venus Mock] Creating request with ID:", requestId);
1822
1858
  return new Promise((resolve) => {
1823
1859
  venusApi._mock.pendingRequests[requestId] = { resolve };
1824
1860
  const id = notificationId || `mock-notification-${Date.now()}`;
@@ -1840,8 +1876,13 @@ var MockNotificationsApi = class {
1840
1876
  async setLocalNotificationsEnabled(enabled) {
1841
1877
  const venusApi = this.venusApi;
1842
1878
  if (isWebPlatform()) {
1879
+ console.log(
1880
+ "[Venus Mock] Set notifications enabled on web platform (simulated):",
1881
+ enabled
1882
+ );
1843
1883
  return true;
1844
1884
  }
1885
+ console.log("[Venus Mock] Set local notifications enabled:", enabled);
1845
1886
  await createMockDelay(MOCK_DELAYS.short);
1846
1887
  venusApi._mock.notificationsEnabled = enabled;
1847
1888
  return enabled;
@@ -2066,20 +2107,16 @@ function initializePopups(venusApi, host) {
2066
2107
 
2067
2108
  // src/profile/HostProfileApi.ts
2068
2109
  var HostProfileApi = class {
2069
- constructor(venusApi) {
2070
- __publicField(this, "venusApi");
2071
- this.venusApi = venusApi;
2072
- }
2073
2110
  getCurrentProfile() {
2074
- const profile = this.venusApi._profileData;
2111
+ const profile = window.venus?.profile;
2075
2112
  if (!profile) {
2076
2113
  throw new Error(
2077
- "[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
2114
+ "[Venus SDK] Host profile handshake did not complete. Await VenusAPI.initializeAsync() so INIT_SDK can deliver the profile before calling profile APIs."
2078
2115
  );
2079
2116
  }
2080
2117
  if (!profile.id || !profile.username) {
2081
2118
  throw new Error(
2082
- "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
2119
+ "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply real credentials before rooms APIs are used."
2083
2120
  );
2084
2121
  }
2085
2122
  return {
@@ -2093,10 +2130,6 @@ var HostProfileApi = class {
2093
2130
 
2094
2131
  // src/profile/MockProfileApi.ts
2095
2132
  var MockProfileApi = class {
2096
- constructor(venusApi) {
2097
- __publicField(this, "venusApi");
2098
- this.venusApi = venusApi;
2099
- }
2100
2133
  getCurrentProfile() {
2101
2134
  return {
2102
2135
  id: "mock_profile_123",
@@ -2109,22 +2142,11 @@ var MockProfileApi = class {
2109
2142
 
2110
2143
  // src/profile/index.ts
2111
2144
  function initializeProfile(venusApi, host) {
2112
- venusApi.getProfile = () => {
2113
- return host.profile.getCurrentProfile();
2114
- };
2115
2145
  venusApi.getCurrentProfile = () => {
2116
- console.warn(
2117
- "[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
2118
- );
2119
2146
  return host.profile.getCurrentProfile();
2120
2147
  };
2121
2148
  }
2122
2149
 
2123
- // src/utils/idGenerator.ts
2124
- function generateId() {
2125
- return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2126
- }
2127
-
2128
2150
  // src/rpc/RpcClient.ts
2129
2151
  var RpcClient = class {
2130
2152
  constructor() {
@@ -2167,7 +2189,7 @@ var RpcClient = class {
2167
2189
  }
2168
2190
  async call(method, args, timeout = 5e3) {
2169
2191
  return new Promise((resolve, reject) => {
2170
- const id = generateId();
2192
+ const id = this.generateId();
2171
2193
  this.addPendingCall(id, resolve, reject);
2172
2194
  const request = {
2173
2195
  type: "rpc-request",
@@ -2204,6 +2226,9 @@ var RpcClient = class {
2204
2226
  getPendingCall(id) {
2205
2227
  return this.pendingCalls.get(id);
2206
2228
  }
2229
+ generateId() {
2230
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2231
+ }
2207
2232
  handleRpcResponse(response) {
2208
2233
  const pending = this.getPendingCall(response.id);
2209
2234
  if (!pending) {
@@ -2225,449 +2250,32 @@ var RpcClient = class {
2225
2250
  }
2226
2251
  };
2227
2252
 
2228
- // src/rooms/VenusRoom.ts
2229
- var VenusRoom = class {
2230
- constructor(roomData) {
2231
- __publicField(this, "id");
2232
- __publicField(this, "name");
2233
- __publicField(this, "players");
2234
- __publicField(this, "maxPlayers");
2235
- __publicField(this, "gameType");
2236
- __publicField(this, "appId");
2237
- __publicField(this, "type");
2238
- __publicField(this, "createdBy");
2239
- __publicField(this, "createdAt");
2240
- __publicField(this, "updatedAt");
2241
- __publicField(this, "isPrivate");
2242
- __publicField(this, "status");
2243
- __publicField(this, "customMetadata");
2244
- __publicField(this, "admins");
2245
- __publicField(this, "roomCode");
2246
- __publicField(this, "description");
2247
- __publicField(this, "data");
2248
- __publicField(this, "version");
2249
- this.id = roomData.id;
2250
- this.name = roomData.name;
2251
- this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
2252
- this.maxPlayers = roomData.maxPlayers;
2253
- this.gameType = roomData.gameType;
2254
- this.appId = roomData.appId;
2255
- this.type = roomData.type;
2256
- this.createdBy = roomData.createdBy;
2257
- this.createdAt = roomData.createdAt;
2258
- this.updatedAt = roomData.updatedAt;
2259
- this.isPrivate = roomData.isPrivate;
2260
- this.status = roomData.status;
2261
- this.customMetadata = roomData.customMetadata || {};
2262
- this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
2263
- this.roomCode = roomData.roomCode;
2264
- this.description = roomData.description;
2265
- this.data = roomData.data || {};
2266
- this.version = roomData.version;
2267
- }
2268
- };
2253
+ // src/index.ts
2254
+ init_rooms();
2269
2255
 
2270
- // src/rooms/setupRoomNotifications.ts
2271
- function invokeCallbacks(callbacks, event, context) {
2272
- callbacks.forEach((callback) => {
2273
- try {
2274
- callback(event);
2275
- } catch (error) {
2276
- console.error(`[Venus SDK] Error in ${context} callback:`, error);
2277
- throw error;
2278
- }
2279
- });
2280
- }
2281
- function setupRoomNotifications(transport, getSubscriptions) {
2282
- return transport.onVenusMessage((message) => {
2283
- const subscriptions = getSubscriptions();
2284
- if (!subscriptions) {
2285
- return;
2286
- }
2287
- if (message.type === "H5_ROOM_DATA_UPDATED") {
2288
- const messageData = message.data;
2289
- const { roomId, roomData } = messageData;
2290
- if (!roomId) return;
2291
- const callbacks = subscriptions.data[roomId] || [];
2292
- const event = {
2293
- type: "H5_ROOM_DATA_UPDATED",
2294
- roomId,
2295
- roomData,
2296
- timestamp: messageData.timestamp
2297
- };
2298
- invokeCallbacks(callbacks, event, "room data");
2299
- }
2300
- if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
2301
- const messageData = message.data;
2302
- const { roomId } = messageData;
2303
- if (!roomId) return;
2304
- const callbacks = subscriptions.messages[roomId] || [];
2305
- const event = {
2306
- type: message.type,
2307
- roomId,
2308
- message: messageData.message,
2309
- timestamp: messageData.timestamp
2310
- };
2311
- invokeCallbacks(callbacks, event, "room message");
2312
- }
2313
- if (message.type === "app:h5:proposedMoveValidationUpdated") {
2314
- const messageData = message.data;
2315
- const { roomId } = messageData;
2316
- if (!roomId) return;
2317
- const callbacks = subscriptions.gameEvents[roomId] || [];
2318
- const event = {
2319
- type: "app:h5:proposedMoveValidationUpdated",
2320
- roomId,
2321
- proposedMoveData: messageData.proposedMoveData,
2322
- proposedMoveId: messageData.proposedMoveId,
2323
- changeType: messageData.changeType,
2324
- timestamp: messageData.timestamp
2325
- };
2326
- invokeCallbacks(callbacks, event, "game event");
2327
- }
2328
- });
2329
- }
2330
-
2331
- // src/rooms/RpcRoomsApi.ts
2332
- var RpcRoomsApi = class {
2333
- constructor(rpcClient) {
2334
- __publicField(this, "rpcClient");
2335
- __publicField(this, "subscriptions");
2336
- this.rpcClient = rpcClient;
2337
- this.subscriptions = {
2338
- data: {},
2339
- messages: {},
2340
- gameEvents: {}
2341
- };
2342
- }
2343
- /**
2344
- * Get the subscription state for external access (used by setupRoomNotifications)
2345
- */
2346
- getSubscriptions() {
2347
- return this.subscriptions;
2348
- }
2349
- /**
2350
- * Set up room notification routing from the transport
2351
- */
2352
- setupNotifications(transport) {
2353
- setupRoomNotifications(transport, () => this.getSubscriptions());
2354
- }
2355
- async createRoomAsync(options) {
2356
- const response = await this.rpcClient.call(
2357
- "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
2358
- {
2359
- options
2360
- }
2361
- );
2362
- if (response.success === false) {
2363
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
2364
- throw new Error(errorMessage);
2365
- }
2366
- const room = new VenusRoom(response.roomData);
2367
- return room;
2368
- }
2369
- async joinOrCreateRoomAsync(options) {
2370
- const response = await this.rpcClient.call(
2371
- "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
2372
- {
2373
- options
2374
- }
2375
- );
2376
- if (response.success === false) {
2377
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
2378
- throw new Error(errorMessage);
2379
- }
2380
- const room = new VenusRoom(response.value.roomData);
2381
- return {
2382
- action: response.value.action,
2383
- room,
2384
- playersJoined: response.value.playersJoined
2385
- };
2386
- }
2387
- async joinRoomByCodeAsync(roomCode) {
2388
- const response = await this.rpcClient.call(
2389
- "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
2390
- {
2391
- roomCode
2392
- }
2393
- );
2394
- if (response?.success === false) {
2395
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
2396
- throw new Error(errorMessage);
2397
- }
2398
- const room = new VenusRoom(response.roomData);
2399
- return room;
2400
- }
2401
- // Get user's rooms with optional filtering
2402
- async getUserRoomsAsync(options = {}) {
2403
- const response = await this.rpcClient.call(
2404
- "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
2405
- {
2406
- includeArchived: options.includeArchived ?? false
2407
- }
2408
- );
2409
- if (response?.success === false) {
2410
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
2411
- throw new Error(errorMessage);
2412
- }
2413
- const venusRooms = [];
2414
- for (const roomData of response.rooms) {
2415
- if (!roomData.id) {
2416
- console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
2417
- continue;
2418
- }
2419
- try {
2420
- const venusRoom = new VenusRoom(roomData);
2421
- venusRooms.push(venusRoom);
2422
- } catch (error) {
2423
- console.warn(
2424
- "[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
2425
- error,
2426
- roomData
2427
- );
2428
- }
2429
- }
2430
- return venusRooms;
2431
- }
2432
- async updateRoomDataAsync(room, updates, options = {}) {
2433
- const response = await this.rpcClient.call(
2434
- "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
2435
- {
2436
- roomId: room.id,
2437
- updates,
2438
- merge: options.merge ?? true
2439
- }
2440
- );
2441
- if (response?.success === false) {
2442
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
2443
- throw new Error(errorMessage);
2444
- }
2445
- }
2446
- async getRoomDataAsync(room) {
2447
- const response = await this.rpcClient.call(
2448
- "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
2449
- {
2450
- roomId: room.id
2451
- }
2452
- );
2453
- if (response?.success === false) {
2454
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
2455
- throw new Error(errorMessage);
2456
- }
2457
- return response.data;
2458
- }
2459
- async sendRoomMessageAsync(venusRoom, request) {
2460
- const response = await this.rpcClient.call(
2461
- "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
2462
- {
2463
- roomId: venusRoom.id,
2464
- message: request.message,
2465
- metadata: request.metadata
2466
- }
2467
- );
2468
- if (response?.success === false) {
2469
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
2470
- throw new Error(errorMessage);
2471
- }
2472
- return response.messageId;
2473
- }
2474
- async leaveRoomAsync(room) {
2475
- const response = await this.rpcClient.call(
2476
- "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
2477
- {
2478
- roomId: room.id
2479
- }
2480
- );
2481
- if (response?.success === false) {
2482
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
2483
- throw new Error(errorMessage);
2484
- }
2485
- }
2486
- async startRoomGameAsync(room, options = {}) {
2487
- const response = await this.rpcClient.call(
2488
- "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
2489
- {
2490
- roomId: room.id,
2491
- gameConfig: options.gameConfig ?? {},
2492
- turnOrder: options.turnOrder ?? null
2493
- }
2494
- );
2495
- if (response?.success === false) {
2496
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
2497
- throw new Error(errorMessage);
2498
- }
2499
- }
2500
- async proposeMoveAsync(room, proposalPayload) {
2501
- const response = await this.rpcClient.call(
2502
- "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
2503
- {
2504
- roomId: room.id,
2505
- gameSpecificState: proposalPayload.gameSpecificState,
2506
- moveType: proposalPayload.moveType,
2507
- clientContext: proposalPayload.clientContext,
2508
- clientProposalId: proposalPayload.clientProposalId
2509
- }
2510
- );
2511
- if (response?.success === false) {
2512
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
2513
- throw new Error(errorMessage);
2514
- }
2515
- return response.data;
2516
- }
2517
- async validateMoveAsync(_room, moveId, verdict) {
2518
- return {
2519
- success: true,
2520
- moveId,
2521
- isValid: verdict.isValid,
2522
- reason: verdict.reason
2523
- };
2524
- }
2525
- async subscribeAsync(room, options = {}) {
2526
- const roomId = room.id;
2527
- const existingData = this.subscriptions.data[roomId];
2528
- const existingMessages = this.subscriptions.messages[roomId];
2529
- const existingGameEvents = this.subscriptions.gameEvents[roomId];
2530
- const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
2531
- const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
2532
- const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
2533
- if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
2534
- try {
2535
- await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
2536
- roomId,
2537
- subscribeToData,
2538
- subscribeToMessages,
2539
- subscribeToProposedMoves
2540
- });
2541
- } catch (error) {
2542
- console.error("[Venus SDK] Failed to set up room subscription:", error);
2543
- throw error;
2544
- }
2545
- }
2546
- if (options.onData) {
2547
- if (!this.subscriptions.data[roomId]) {
2548
- this.subscriptions.data[roomId] = [];
2549
- }
2550
- this.subscriptions.data[roomId].push(options.onData);
2551
- }
2552
- if (options.onMessages) {
2553
- if (!this.subscriptions.messages[roomId]) {
2554
- this.subscriptions.messages[roomId] = [];
2555
- }
2556
- this.subscriptions.messages[roomId].push(options.onMessages);
2557
- }
2558
- if (options.onGameEvents) {
2559
- if (!this.subscriptions.gameEvents[roomId]) {
2560
- this.subscriptions.gameEvents[roomId] = [];
2561
- }
2562
- this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
2563
- }
2564
- let disposed = false;
2565
- return () => {
2566
- if (disposed) return;
2567
- disposed = true;
2568
- if (options.onData) {
2569
- const callbacks = this.subscriptions.data[roomId];
2570
- if (callbacks) {
2571
- const index = callbacks.indexOf(options.onData);
2572
- if (index > -1) {
2573
- callbacks.splice(index, 1);
2574
- }
2575
- }
2576
- }
2577
- if (options.onMessages) {
2578
- const callbacks = this.subscriptions.messages[roomId];
2579
- if (callbacks) {
2580
- const index = callbacks.indexOf(options.onMessages);
2581
- if (index > -1) {
2582
- callbacks.splice(index, 1);
2583
- }
2584
- }
2585
- }
2586
- if (options.onGameEvents) {
2587
- const callbacks = this.subscriptions.gameEvents[roomId];
2588
- if (callbacks) {
2589
- const index = callbacks.indexOf(options.onGameEvents);
2590
- if (index > -1) {
2591
- callbacks.splice(index, 1);
2592
- }
2593
- }
2594
- }
2595
- const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
2596
- if (!hasAnySubscriptions) {
2597
- this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
2598
- roomId
2599
- }).catch((error) => {
2600
- console.error("[Venus SDK] Failed to clean up room subscription:", error);
2601
- });
2602
- }
2603
- };
2604
- }
2605
- };
2606
-
2607
- // src/rooms/index.ts
2608
- function bindMethod(target, targetKey, source, sourceKey) {
2609
- const key = sourceKey ?? targetKey;
2610
- const fn = source?.[key];
2611
- if (typeof fn === "function") {
2612
- target[targetKey] = fn.bind(source);
2613
- return true;
2614
- }
2615
- return false;
2616
- }
2617
- function initializeRoomsApi(venusApi, host) {
2618
- const roomsApi = host?.rooms;
2619
- if (!roomsApi) {
2620
- console.warn(
2621
- "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
2622
- );
2623
- return;
2624
- }
2625
- const venus = venusApi;
2626
- const existingNamespace = venus.rooms || {};
2627
- const roomsNamespace = Object.assign({}, existingNamespace);
2628
- const namespaceBindings = [
2629
- ["createRoomAsync"],
2630
- ["joinOrCreateRoomAsync"],
2631
- ["joinRoomByCodeAsync"],
2632
- ["getUserRoomsAsync"],
2633
- ["subscribeAsync"],
2634
- ["updateRoomDataAsync"],
2635
- ["getRoomDataAsync"],
2636
- ["sendRoomMessageAsync"],
2637
- ["leaveRoomAsync"],
2638
- ["startRoomGameAsync"],
2639
- ["proposeMoveAsync"],
2640
- ["validateMoveAsync"]
2641
- ];
2642
- namespaceBindings.forEach(([targetKey, sourceKey]) => {
2643
- bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
2644
- });
2645
- venus.rooms = roomsNamespace;
2646
- }
2647
-
2648
- // src/storage/MockStorageApi.ts
2649
- function createMockStorageApi(storageType, appUrl) {
2650
- const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2651
- let prefix;
2652
- let syncDelay = 0;
2653
- switch (storageType) {
2654
- case "deviceCache":
2655
- prefix = "venus:app";
2656
- syncDelay = 0;
2657
- break;
2658
- case "appStorage":
2659
- prefix = "venus:app";
2660
- syncDelay = 100;
2661
- break;
2662
- case "globalStorage":
2663
- prefix = "venus:global";
2664
- syncDelay = 100;
2665
- break;
2666
- default:
2667
- throw new Error(`Unknown storage type: ${storageType}`);
2668
- }
2669
- prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2670
- return new MockStorageApi(prefix, syncDelay);
2256
+ // src/storage/MockStorageApi.ts
2257
+ function createMockStorageApi(storageType, appUrl) {
2258
+ const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2259
+ let prefix;
2260
+ let syncDelay = 0;
2261
+ switch (storageType) {
2262
+ case "deviceCache":
2263
+ prefix = "venus:app";
2264
+ syncDelay = 0;
2265
+ break;
2266
+ case "appStorage":
2267
+ prefix = "venus:app";
2268
+ syncDelay = 100;
2269
+ break;
2270
+ case "globalStorage":
2271
+ prefix = "venus:global";
2272
+ syncDelay = 100;
2273
+ break;
2274
+ default:
2275
+ throw new Error(`Unknown storage type: ${storageType}`);
2276
+ }
2277
+ prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2278
+ return new MockStorageApi(prefix, syncDelay);
2671
2279
  }
2672
2280
  var MockStorageApi = class {
2673
2281
  constructor(prefix, syncDelay) {
@@ -2878,20 +2486,24 @@ function initializeStorage(venusApiInstance, host) {
2878
2486
  venusApiInstance.globalStorage = host.globalStorage;
2879
2487
  }
2880
2488
 
2489
+ // src/simulation/utils.ts
2490
+ function sumContributions(contributions) {
2491
+ const totals = {};
2492
+ for (const profileId in contributions) {
2493
+ for (const entityId in contributions[profileId]) {
2494
+ const amount = contributions[profileId][entityId] || 0;
2495
+ totals[entityId] = (totals[entityId] || 0) + amount;
2496
+ }
2497
+ }
2498
+ return totals;
2499
+ }
2500
+
2881
2501
  // src/simulation/RpcSimulationApi.ts
2882
2502
  var RpcSimulationApi = class {
2883
2503
  constructor(rpcClient) {
2884
2504
  __publicField(this, "rpcClient");
2885
2505
  __publicField(this, "_simulationConfig", null);
2886
- __publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
2887
2506
  this.rpcClient = rpcClient;
2888
- this.rpcClient.onNotification(
2889
- "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
2890
- this.handleSimulationUpdate.bind(this)
2891
- );
2892
- }
2893
- isEnabled() {
2894
- return true;
2895
2507
  }
2896
2508
  async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2897
2509
  return this.rpcClient.call(
@@ -2903,47 +2515,14 @@ var RpcSimulationApi = class {
2903
2515
  }
2904
2516
  );
2905
2517
  }
2906
- async subscribeAsync(options) {
2907
- this.ensureValidSubscribeOptions(options);
2908
- const subscriptionId = generateId();
2909
- this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
2910
- try {
2911
- await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
2912
- subscriptionId,
2913
- entities: options.entities,
2914
- tags: options.tags,
2915
- activeRuns: options.activeRuns,
2916
- roomId: options.roomId
2917
- });
2918
- } catch (error) {
2919
- this.subscriptionCallbacks.delete(subscriptionId);
2920
- throw error;
2921
- }
2922
- let unsubscribed = false;
2923
- return () => {
2924
- if (unsubscribed) {
2925
- return;
2926
- }
2927
- unsubscribed = true;
2928
- this.subscriptionCallbacks.delete(subscriptionId);
2929
- void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
2930
- subscriptionId
2931
- }).catch((error) => {
2932
- console.error(
2933
- "[Venus SDK] Failed to unsubscribe simulation listener",
2934
- error
2935
- );
2936
- });
2937
- };
2518
+ sumContributions(contributions) {
2519
+ return sumContributions(contributions);
2938
2520
  }
2939
2521
  executeBatchOperationsAsync(operations, validateOnly) {
2940
- return this.rpcClient.call(
2941
- "H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
2942
- {
2943
- operations,
2944
- validateOnly
2945
- }
2946
- );
2522
+ return this.rpcClient.call("H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */, {
2523
+ operations,
2524
+ validateOnly
2525
+ });
2947
2526
  }
2948
2527
  async getAvailableItemsAsync(containerId, slotId) {
2949
2528
  const response = await this.rpcClient.call(
@@ -2966,23 +2545,17 @@ var RpcSimulationApi = class {
2966
2545
  );
2967
2546
  }
2968
2547
  assignItemToSlotAsync(containerId, slotId, itemId) {
2969
- return this.rpcClient.call(
2970
- "H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
2971
- {
2972
- containerId,
2973
- slotId,
2974
- itemId
2975
- }
2976
- );
2548
+ return this.rpcClient.call("H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */, {
2549
+ containerId,
2550
+ slotId,
2551
+ itemId
2552
+ });
2977
2553
  }
2978
2554
  removeItemFromSlotAsync(containerId, slotId) {
2979
- return this.rpcClient.call(
2980
- "H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
2981
- {
2982
- containerId,
2983
- slotId
2984
- }
2985
- );
2555
+ return this.rpcClient.call("H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */, {
2556
+ containerId,
2557
+ slotId
2558
+ });
2986
2559
  }
2987
2560
  async getSlotContainersAsync() {
2988
2561
  const response = await this.rpcClient.call(
@@ -3007,6 +2580,7 @@ var RpcSimulationApi = class {
3007
2580
  roomId
3008
2581
  }
3009
2582
  );
2583
+ console.log("[Venus SDK] getStateAsync", response);
3010
2584
  if (response.configuration) {
3011
2585
  this._simulationConfig = response.configuration;
3012
2586
  }
@@ -3018,10 +2592,9 @@ var RpcSimulationApi = class {
3018
2592
  }
3019
2593
  const config = await this.rpcClient.call(
3020
2594
  "H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
3021
- {
3022
- roomId
3023
- }
2595
+ {}
3024
2596
  );
2597
+ console.log("[Venus SDK] getConfigAsync", config);
3025
2598
  if (config) {
3026
2599
  this._simulationConfig = config;
3027
2600
  return config;
@@ -3029,17 +2602,14 @@ var RpcSimulationApi = class {
3029
2602
  throw new Error("No simulation configuration available");
3030
2603
  }
3031
2604
  executeRecipeAsync(recipeId, inputs, options) {
3032
- return this.rpcClient.call(
3033
- "H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
3034
- {
3035
- recipeId,
3036
- inputs,
3037
- roomId: options?.roomId,
3038
- batchAmount: options?.batchAmount,
3039
- allowPartialBatch: options?.allowPartialBatch,
3040
- entity: options?.entity
3041
- }
3042
- );
2605
+ return this.rpcClient.call("H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */, {
2606
+ recipeId,
2607
+ inputs,
2608
+ roomId: options?.roomId,
2609
+ batchAmount: options?.batchAmount,
2610
+ allowPartialBatch: options?.allowPartialBatch,
2611
+ entity: options?.entity
2612
+ });
3043
2613
  }
3044
2614
  collectRecipeAsync(runId) {
3045
2615
  return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
@@ -3047,12 +2617,9 @@ var RpcSimulationApi = class {
3047
2617
  });
3048
2618
  }
3049
2619
  getActiveRunsAsync(options) {
3050
- return this.rpcClient.call(
3051
- "H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
3052
- {
3053
- roomId: options?.roomId
3054
- }
3055
- );
2620
+ return this.rpcClient.call("H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */, {
2621
+ roomId: options?.roomId
2622
+ });
3056
2623
  }
3057
2624
  executeScopedRecipeAsync(recipeId, entity, inputs, options) {
3058
2625
  return this.rpcClient.call(
@@ -3111,63 +2678,594 @@ var RpcSimulationApi = class {
3111
2678
  }
3112
2679
  );
3113
2680
  }
3114
- async resolveFieldValueAsync(entityId, fieldPath, entity) {
3115
- const response = await this.rpcClient.call(
3116
- "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
3117
- {
3118
- entityId,
3119
- fieldPath,
3120
- entity
3121
- }
3122
- );
3123
- return response.value;
2681
+ async resolveFieldValueAsync(entityId, fieldPath, entity) {
2682
+ const response = await this.rpcClient.call(
2683
+ "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
2684
+ {
2685
+ entityId,
2686
+ fieldPath,
2687
+ entity
2688
+ }
2689
+ );
2690
+ return response.value;
2691
+ }
2692
+ };
2693
+
2694
+ // src/simulation/MockSimulationApi.ts
2695
+ function generateAppIdentifier2() {
2696
+ if (typeof window === "undefined") return "unknown-app";
2697
+ const url = window.location.href;
2698
+ const match = url.match(/\/H5\/([^\/]+)/);
2699
+ return match ? match[1] : "unknown-app";
2700
+ }
2701
+ var MockSimulationApi = class {
2702
+ constructor(simulationConfig = null) {
2703
+ __publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
2704
+ // appIdentifier -> config
2705
+ __publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
2706
+ // appIdentifier -> config
2707
+ __publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
2708
+ // appIdentifier -> timers[]
2709
+ __publicField(this, "appId");
2710
+ __publicField(this, "providedSimulationConfig");
2711
+ this.appId = generateAppIdentifier2();
2712
+ this.providedSimulationConfig = simulationConfig;
2713
+ }
2714
+ sumContributions(contributions) {
2715
+ return sumContributions(contributions);
2716
+ }
2717
+ async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2718
+ this.log("validateSlotAssignmentAsync called:", {
2719
+ containerId,
2720
+ slotId,
2721
+ itemId
2722
+ });
2723
+ return { valid: true, message: "Mock validation successful" };
2724
+ }
2725
+ async executeBatchOperationsAsync(operations, validateOnly) {
2726
+ this.log("executeBatchOperationsAsync called:", {
2727
+ operations,
2728
+ validateOnly
2729
+ });
2730
+ return {
2731
+ success: true,
2732
+ results: operations.map(() => ({ success: true }))
2733
+ };
2734
+ }
2735
+ async getAvailableItemsAsync(containerId, slotId) {
2736
+ console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
2737
+ containerId,
2738
+ slotId
2739
+ });
2740
+ const appIdentifier = generateAppIdentifier2();
2741
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2742
+ const config = mockSimulationConfigs.get(appIdentifier) || {
2743
+ entities: {}
2744
+ };
2745
+ const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
2746
+ entityId,
2747
+ quantity: 1,
2748
+ metadata: entity.metadata,
2749
+ powerPreview: 100
2750
+ // Mock power value
2751
+ }));
2752
+ return availableItems;
2753
+ }
2754
+ async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
2755
+ this.log("calculatePowerPreviewAsync called:", {
2756
+ containerId,
2757
+ slotId,
2758
+ candidateItemId
2759
+ });
2760
+ return {
2761
+ currentPower: 1e3,
2762
+ previewPower: 1200,
2763
+ powerDelta: 200,
2764
+ breakdown: { base: 800, weapon: 200, armor: 200 }
2765
+ };
2766
+ }
2767
+ async getSlotContainersAsync() {
2768
+ this.log("getSlotContainersAsync called");
2769
+ const appIdentifier = this.appId;
2770
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2771
+ const config = mockSimulationConfigs.get(appIdentifier) || {
2772
+ entities: {}
2773
+ };
2774
+ const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
2775
+ entityId,
2776
+ slots: entity.metadata?.slots,
2777
+ isOwned: true
2778
+ // Mock: assume all containers are owned
2779
+ }));
2780
+ return containers;
2781
+ }
2782
+ async getSlotAssignmentsAsync(containerId) {
2783
+ this.log("getSlotAssignmentsAsync called for:", containerId);
2784
+ return [];
2785
+ }
2786
+ async resolveFieldValueAsync(entityId, fieldPath, entity) {
2787
+ this.log("resolveFieldValueAsync called:", {
2788
+ entityId,
2789
+ fieldPath,
2790
+ entity
2791
+ });
2792
+ const mockValues = {
2793
+ basePower: 850,
2794
+ weaponPower: 300,
2795
+ armorPower: 150,
2796
+ total_power: 1300,
2797
+ total_defense_power: 5e3
2798
+ };
2799
+ return mockValues[fieldPath] || 100;
2800
+ }
2801
+ async getEntityMetadataAsync(entityId) {
2802
+ this.log("getEntityMetadataAsync called for:", entityId);
2803
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2804
+ const appIdentifier = this.appId;
2805
+ const config = mockSimulationConfigs.get(
2806
+ appIdentifier
2807
+ ) || {
2808
+ entities: {}};
2809
+ const entity = config.entities[entityId];
2810
+ return entity?.metadata || {};
2811
+ }
2812
+ async collectRecipeAsync(runId) {
2813
+ this.log("collectRecipeAsync called:", { runId });
2814
+ const mockRewards = {
2815
+ cash: Math.floor(Math.random() * 1e3) + 500,
2816
+ experience: Math.floor(Math.random() * 50) + 25
2817
+ };
2818
+ return {
2819
+ success: true,
2820
+ runId,
2821
+ rewards: mockRewards,
2822
+ message: "Rewards collected successfully"
2823
+ };
2824
+ }
2825
+ executeRecipeAsync(recipeId, inputs, options) {
2826
+ this.log("executeRecipeAsync called:", {
2827
+ recipeId,
2828
+ inputs,
2829
+ options
2830
+ });
2831
+ const appIdentifier = this.appId;
2832
+ return this.executeRecipe(appIdentifier, recipeId, inputs);
2833
+ }
2834
+ async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
2835
+ this.log("executeScopedRecipeAsync called:", {
2836
+ recipeId,
2837
+ entity,
2838
+ inputs,
2839
+ roomId: options?.roomId,
2840
+ options
2841
+ });
2842
+ return {
2843
+ success: true,
2844
+ message: "Mock scoped recipe execution successful"
2845
+ };
2846
+ }
2847
+ async getActiveRunsAsync(options) {
2848
+ this.log("getActiveRunsAsync called:", options);
2849
+ const appIdentifier = this.appId;
2850
+ let state = this.mockSimulationStates.get(appIdentifier);
2851
+ if (!state) {
2852
+ state = await this.initializeSimulationState(appIdentifier);
2853
+ }
2854
+ return state.activeRuns || [];
2855
+ }
2856
+ async getAvailableRecipesAsync(options) {
2857
+ this.log("getAvailableRecipesAsync called:", options);
2858
+ const baseRecipes = [
2859
+ { id: "collect_resources", scope: "player", clientViewable: true },
2860
+ { id: "upgrade_equipment", scope: "player", clientViewable: true }
2861
+ ];
2862
+ if (options?.roomId) {
2863
+ baseRecipes.push(
2864
+ { id: "room_upgrade", scope: "room", clientViewable: true },
2865
+ { id: "cooperative_project", scope: "room", clientViewable: true }
2866
+ );
2867
+ }
2868
+ if (options?.includeActorRecipes && options?.roomId) {
2869
+ baseRecipes.push(
2870
+ { id: "trade_with_npc", scope: "actor", clientViewable: true },
2871
+ { id: "attack_monster", scope: "actor", clientViewable: true }
2872
+ );
2873
+ }
2874
+ return { success: true, recipes: baseRecipes };
2875
+ }
2876
+ async getBatchRecipeRequirementsAsync(recipes) {
2877
+ this.log("getBatchRecipeRequirementsAsync called:", {
2878
+ count: recipes?.length
2879
+ });
2880
+ const results = (recipes || []).map((q) => ({
2881
+ recipeId: q.recipeId,
2882
+ entity: q.entity || null,
2883
+ amount: q.batchAmount || 1,
2884
+ inputs: { cash: "BE:0" },
2885
+ canAfford: true,
2886
+ disabled: false
2887
+ }));
2888
+ return { success: true, results };
2889
+ }
2890
+ async getRecipeRequirementsAsync(recipe) {
2891
+ this.log("getRecipeRequirementsAsync called:", recipe);
2892
+ return {
2893
+ recipeId: recipe.recipeId,
2894
+ entity: recipe.entity || null,
2895
+ amount: recipe.batchAmount,
2896
+ inputs: { cash: "BE:0" },
2897
+ canAfford: true,
2898
+ disabled: false
2899
+ };
2900
+ }
2901
+ async triggerRecipeChainAsync(recipeId, options) {
2902
+ this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
2903
+ return {
2904
+ success: true,
2905
+ message: "Mock recipe chain triggered successfully"
2906
+ };
3124
2907
  }
3125
- handleSimulationUpdate(notification) {
3126
- if (!notification || !notification.subscriptionId) {
3127
- console.warn("[Venus SDK] Received malformed simulation update");
3128
- return;
2908
+ log(message, ...args) {
2909
+ console.log(`[Venus Sim Mock] ${message}`, args);
2910
+ }
2911
+ async executeRecipe(appIdentifier, recipeId, inputs) {
2912
+ this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
2913
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2914
+ const mockSimulationStates = this.mockSimulationStates;
2915
+ let config = mockSimulationConfigs.get(appIdentifier);
2916
+ let state = mockSimulationStates.get(appIdentifier);
2917
+ if (!config || !state) {
2918
+ state = await this.initializeSimulationState(appIdentifier);
2919
+ config = mockSimulationConfigs.get(appIdentifier);
2920
+ if (!config) {
2921
+ throw new Error("Failed to initialize simulation config");
2922
+ }
3129
2923
  }
3130
- const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
3131
- if (!callback) {
3132
- console.warn(
3133
- "[Venus SDK] Received update for unknown subscription:",
3134
- notification.subscriptionId
3135
- );
3136
- return;
2924
+ const recipe = config.recipes?.[recipeId];
2925
+ if (!recipe) {
2926
+ throw new Error(`Recipe ${recipeId} not found`);
3137
2927
  }
3138
- try {
3139
- callback(notification.updates);
3140
- } catch (error) {
3141
- console.error("[Venus SDK] Error in simulation subscription callback", error);
2928
+ if (state.disabledRecipes?.includes(recipeId)) {
2929
+ throw new Error(`Recipe ${recipeId} is disabled`);
2930
+ }
2931
+ if (recipe.inputs) {
2932
+ for (const [entityId, required] of Object.entries(recipe.inputs)) {
2933
+ const available = state.inventory[entityId] || 0;
2934
+ if (available < required) {
2935
+ throw new Error(
2936
+ `Insufficient ${entityId}: required ${required}, available ${available}`
2937
+ );
2938
+ }
2939
+ }
2940
+ }
2941
+ if (recipe.inputs) {
2942
+ for (const [entityId, input] of Object.entries(recipe.inputs)) {
2943
+ const inventoryValue = state.inventory[entityId] || 0;
2944
+ if (typeof input === "number" && typeof inventoryValue === "number") {
2945
+ state.inventory[entityId] = inventoryValue - input;
2946
+ }
2947
+ }
2948
+ }
2949
+ if (recipe.beginEffects) {
2950
+ this.applyEffects(state, recipe.beginEffects);
2951
+ }
2952
+ const runId = this.generateRunId();
2953
+ const now = Date.now();
2954
+ const expiresAt = now + (recipe.duration || 0);
2955
+ const run = {
2956
+ id: runId,
2957
+ recipeId,
2958
+ status: "running",
2959
+ startTime: now,
2960
+ expiresAt,
2961
+ inputs: recipe.inputs || {}
2962
+ };
2963
+ state.activeRuns.push(run);
2964
+ if (recipe.duration === 0) {
2965
+ this.completeRun(appIdentifier, runId);
2966
+ return { status: "completed", runId };
2967
+ } else {
2968
+ const mockActiveTimers = this.mockActiveTimers;
2969
+ const timer = setTimeout(() => {
2970
+ this.completeRun(appIdentifier, runId);
2971
+ }, recipe.duration);
2972
+ const timers = mockActiveTimers.get(appIdentifier) || [];
2973
+ timers.push(timer);
2974
+ mockActiveTimers.set(appIdentifier, timers);
2975
+ return {
2976
+ status: "running",
2977
+ runId,
2978
+ expiresAt: new Date(expiresAt).toISOString()
2979
+ };
3142
2980
  }
3143
2981
  }
3144
- ensureValidSubscribeOptions(options) {
3145
- if (typeof options !== "object" || options === null) {
3146
- throw new Error("Simulation subscribe requires an options object");
2982
+ async initializeSimulationState(appIdentifier) {
2983
+ this.log(`Initializing simulation state for ${appIdentifier}`);
2984
+ const providedSimulationConfig = this.providedSimulationConfig;
2985
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2986
+ const mockSimulationStates = this.mockSimulationStates;
2987
+ const mockActiveTimers = this.mockActiveTimers;
2988
+ const config = providedSimulationConfig || {
2989
+ version: "1.0",
2990
+ entities: {},
2991
+ recipes: {}
2992
+ };
2993
+ mockSimulationConfigs.set(appIdentifier, config);
2994
+ const initialInventory = {};
2995
+ if (providedSimulationConfig && config.entities) {
2996
+ Object.keys(config.entities).forEach((entityId) => {
2997
+ initialInventory[entityId] = 0;
2998
+ });
3147
2999
  }
3148
- const opts = options;
3149
- if (typeof opts.onUpdate !== "function") {
3150
- throw new Error("Simulation subscribe requires an onUpdate callback");
3000
+ const state = {
3001
+ inventory: initialInventory,
3002
+ activeRuns: [],
3003
+ disabledRecipes: new Array()
3004
+ };
3005
+ if (config.recipes) {
3006
+ Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
3007
+ if (recipe.metadata?.startsDisabled) {
3008
+ state.disabledRecipes.push(recipeId);
3009
+ }
3010
+ });
3151
3011
  }
3152
- const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
3153
- if (!hasFilter) {
3154
- throw new Error(
3155
- "Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
3012
+ mockSimulationStates.set(appIdentifier, state);
3013
+ mockActiveTimers.set(appIdentifier, []);
3014
+ console.log(
3015
+ `[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
3016
+ state
3017
+ );
3018
+ if (config.recipes) {
3019
+ Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
3020
+ const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
3021
+ if (isAutoRestart && recipe.outputs) {
3022
+ this.log(`Found auto-restart recipe: ${recipeId}`, {
3023
+ topLevelAutoRestart: recipe.autoRestart,
3024
+ metadataAutoRestart: recipe.metadata?.autoRestart,
3025
+ hasOutputs: !!recipe.outputs,
3026
+ duration: recipe.duration
3027
+ });
3028
+ const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
3029
+ if (condition && condition.entity) {
3030
+ const currentAmount = initialInventory[condition.entity] || 0;
3031
+ if (currentAmount < condition.maxValue) {
3032
+ console.log(
3033
+ `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
3034
+ {
3035
+ currentAmount,
3036
+ maxValue: condition.maxValue,
3037
+ entity: condition.entity
3038
+ }
3039
+ );
3040
+ setTimeout(() => {
3041
+ this.executeRecipe(appIdentifier, recipeId, {});
3042
+ }, 1e3);
3043
+ }
3044
+ } else {
3045
+ console.log(
3046
+ `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
3047
+ );
3048
+ setTimeout(() => {
3049
+ this.executeRecipe(appIdentifier, recipeId, {});
3050
+ }, 1e3);
3051
+ }
3052
+ }
3053
+ });
3054
+ }
3055
+ return state;
3056
+ }
3057
+ generateRunId() {
3058
+ return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
3059
+ }
3060
+ completeRun(appIdentifier, runId) {
3061
+ this.log(`Completing run ${runId} for ${appIdentifier}`);
3062
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3063
+ const mockSimulationStates = this.mockSimulationStates;
3064
+ const config = mockSimulationConfigs.get(appIdentifier);
3065
+ const state = mockSimulationStates.get(appIdentifier);
3066
+ if (!config || !state) return;
3067
+ const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
3068
+ if (runIndex === -1) return;
3069
+ const run = state.activeRuns[runIndex];
3070
+ const recipe = config.recipes?.[run.recipeId];
3071
+ if (!recipe) return;
3072
+ const outputs = {};
3073
+ const rng = this.createSeededRandom(runId);
3074
+ if (recipe.outputs) {
3075
+ for (const [entityId, value] of Object.entries(recipe.outputs)) {
3076
+ if (typeof value === "number") {
3077
+ outputs[entityId] = value;
3078
+ } else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
3079
+ outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
3080
+ }
3081
+ }
3082
+ }
3083
+ for (const [entityId, amount] of Object.entries(outputs)) {
3084
+ state.inventory[entityId] = (state.inventory[entityId] || 0) + amount;
3085
+ }
3086
+ if (recipe.endEffects) {
3087
+ this.applyEffects(state, recipe.endEffects);
3088
+ }
3089
+ run.status = "completed";
3090
+ run.outputs = outputs;
3091
+ state.activeRuns.splice(runIndex, 1);
3092
+ const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
3093
+ if (isAutoRestart) {
3094
+ console.log(
3095
+ `[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
3096
+ {
3097
+ topLevelAutoRestart: recipe.autoRestart,
3098
+ metadataAutoRestart: recipe.metadata?.autoRestart,
3099
+ hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
3100
+ }
3156
3101
  );
3102
+ const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
3103
+ if (condition) {
3104
+ const currentAmount = state.inventory[condition.entity] || 0;
3105
+ if (currentAmount < condition.maxValue) {
3106
+ console.log(
3107
+ `[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
3108
+ {
3109
+ currentAmount,
3110
+ maxValue: condition.maxValue,
3111
+ entity: condition.entity
3112
+ }
3113
+ );
3114
+ setTimeout(() => {
3115
+ this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3116
+ }, 1e3);
3117
+ }
3118
+ } else {
3119
+ console.log(
3120
+ `[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
3121
+ );
3122
+ setTimeout(() => {
3123
+ this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3124
+ }, 1e3);
3125
+ }
3157
3126
  }
3127
+ console.log(
3128
+ `[Venus Simulation Mock] Completed run ${runId}, outputs:`,
3129
+ outputs
3130
+ );
3131
+ }
3132
+ createSeededRandom(seed) {
3133
+ let hash = 0;
3134
+ for (let i = 0; i < seed.length; i++) {
3135
+ const char = seed.charCodeAt(i);
3136
+ hash = (hash << 5) - hash + char;
3137
+ hash = hash & hash;
3138
+ }
3139
+ return () => {
3140
+ hash = (hash * 9301 + 49297) % 233280;
3141
+ return hash / 233280;
3142
+ };
3143
+ }
3144
+ applyEffects(state, effects) {
3145
+ if (!effects || !Array.isArray(effects)) return;
3146
+ for (const effect of effects) {
3147
+ switch (effect.type) {
3148
+ case "set":
3149
+ state.inventory[effect.target] = effect.value;
3150
+ console.log(
3151
+ `[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
3152
+ );
3153
+ break;
3154
+ case "add":
3155
+ state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
3156
+ console.log(
3157
+ `[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
3158
+ );
3159
+ break;
3160
+ case "multiply":
3161
+ state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
3162
+ console.log(
3163
+ `[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
3164
+ );
3165
+ break;
3166
+ case "min":
3167
+ state.inventory[effect.target] = Math.max(
3168
+ state.inventory[effect.target] || 0,
3169
+ effect.value
3170
+ );
3171
+ console.log(
3172
+ `[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
3173
+ );
3174
+ break;
3175
+ case "max":
3176
+ state.inventory[effect.target] = Math.min(
3177
+ state.inventory[effect.target] || 0,
3178
+ effect.value
3179
+ );
3180
+ console.log(
3181
+ `[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
3182
+ );
3183
+ break;
3184
+ case "enable_recipe":
3185
+ if (state.disabledRecipes?.includes(effect.target)) {
3186
+ state.disabledRecipes = state.disabledRecipes.filter(
3187
+ (r) => r !== effect.target
3188
+ );
3189
+ console.log(
3190
+ `[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
3191
+ );
3192
+ }
3193
+ break;
3194
+ case "disable_recipe":
3195
+ if (!state.disabledRecipes) state.disabledRecipes = [];
3196
+ if (!state.disabledRecipes.includes(effect.target)) {
3197
+ state.disabledRecipes.push(effect.target);
3198
+ console.log(
3199
+ `[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
3200
+ );
3201
+ }
3202
+ break;
3203
+ case "trigger_recipe":
3204
+ console.log(
3205
+ `[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
3206
+ );
3207
+ break;
3208
+ default:
3209
+ console.warn(
3210
+ `[Venus Simulation Mock] Unknown effect type: ${effect.type}`
3211
+ );
3212
+ }
3213
+ }
3214
+ }
3215
+ async getConfigAsync() {
3216
+ console.log("[Venus Simulation Mock] getConfigAsync called");
3217
+ const appIdentifier = this.appId;
3218
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3219
+ const config = mockSimulationConfigs.get(appIdentifier) || {
3220
+ version: "1.0",
3221
+ entities: {},
3222
+ recipes: {}
3223
+ };
3224
+ return config;
3225
+ }
3226
+ async getStateAsync(roomId) {
3227
+ this.log("getStateAsync called:", roomId);
3228
+ const appIdentifier = this.appId;
3229
+ const mockSimulationStates = this.mockSimulationStates;
3230
+ let state = mockSimulationStates.get(appIdentifier);
3231
+ if (!state) {
3232
+ state = await this.initializeSimulationState(appIdentifier);
3233
+ }
3234
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3235
+ return {
3236
+ ...state,
3237
+ roomId,
3238
+ configuration: mockSimulationConfigs.get(appIdentifier)
3239
+ };
3240
+ }
3241
+ async assignItemToSlotAsync(containerId, slotId, itemId) {
3242
+ this.log("assignItemToSlotAsync called:", {
3243
+ containerId,
3244
+ slotId,
3245
+ itemId
3246
+ });
3247
+ return { success: true, message: "Mock assignment successful" };
3248
+ }
3249
+ async removeItemFromSlotAsync(containerId, slotId) {
3250
+ this.log("removeItemFromSlotAsync called:", {
3251
+ containerId,
3252
+ slotId
3253
+ });
3254
+ return { success: true, message: "Mock removal successful" };
3158
3255
  }
3159
3256
  };
3160
3257
 
3161
3258
  // src/simulation/index.ts
3162
3259
  function initializeSimulation(venusApi, host) {
3260
+ console.log("[Venus SDK] Initializing new Simulation Api");
3163
3261
  venusApi.simulation = {
3164
3262
  isEnabled: () => true
3165
3263
  };
3166
3264
  venusApi.simulation.getConfigAsync = () => {
3167
3265
  return host.simulation.getConfigAsync();
3168
3266
  };
3169
- venusApi.simulation.getStateAsync = (roomId) => {
3170
- return host.simulation.getStateAsync(roomId);
3267
+ venusApi.simulation.getStateAsync = (options) => {
3268
+ return host.simulation.getStateAsync(options?.roomId);
3171
3269
  };
3172
3270
  venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
3173
3271
  return host.simulation.executeRecipeAsync(recipeId, inputs, options);
@@ -3178,17 +3276,31 @@ function initializeSimulation(venusApi, host) {
3178
3276
  venusApi.simulation.collectRecipeAsync = (runId) => {
3179
3277
  return host.simulation.collectRecipeAsync(runId);
3180
3278
  };
3181
- venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
3182
- return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
3279
+ venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, roomId, options) => {
3280
+ return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, {
3281
+ roomId,
3282
+ ...options
3283
+ });
3183
3284
  };
3184
- venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
3185
- return host.simulation.triggerRecipeChainAsync(recipeId, options);
3285
+ venusApi.simulation.triggerRecipeChainAsync = (recipeId, context, roomId) => {
3286
+ return host.simulation.triggerRecipeChainAsync(recipeId, {
3287
+ context,
3288
+ roomId
3289
+ });
3186
3290
  };
3187
- venusApi.simulation.getAvailableRecipesAsync = async (options) => {
3188
- return host.simulation.getAvailableRecipesAsync(options);
3291
+ venusApi.simulation.getAvailableRecipesAsync = async (roomId, includeActorRecipes) => {
3292
+ const result = await host.simulation.getAvailableRecipesAsync({
3293
+ roomId,
3294
+ includeActorRecipes
3295
+ });
3296
+ return result.recipes;
3189
3297
  };
3190
- venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
3191
- return host.simulation.getRecipeRequirementsAsync(recipe);
3298
+ venusApi.simulation.getRecipeRequirementsAsync = (recipeId, entity, amount) => {
3299
+ return host.simulation.getRecipeRequirementsAsync({
3300
+ recipeId,
3301
+ entity,
3302
+ batchAmount: amount
3303
+ });
3192
3304
  };
3193
3305
  venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
3194
3306
  return host.simulation.getBatchRecipeRequirementsAsync(recipes);
@@ -3231,6 +3343,9 @@ function initializeSimulation(venusApi, host) {
3231
3343
  itemId
3232
3344
  );
3233
3345
  };
3346
+ venusApi.simulation.sumContributions = (contributions) => {
3347
+ return host.simulation.sumContributions(contributions);
3348
+ };
3234
3349
  }
3235
3350
 
3236
3351
  // src/time/utils.ts
@@ -3249,11 +3364,9 @@ function isPacificDaylightTime(date) {
3249
3364
 
3250
3365
  // src/time/HostTimeApi.ts
3251
3366
  var HostTimeApi = class {
3252
- constructor(rpcClient, venusApi) {
3367
+ constructor(rpcClient) {
3253
3368
  __publicField(this, "rpcClient");
3254
- __publicField(this, "venusApi");
3255
3369
  this.rpcClient = rpcClient;
3256
- this.venusApi = venusApi;
3257
3370
  }
3258
3371
  async requestTimeAsync() {
3259
3372
  const response = await this.rpcClient.call(
@@ -3263,7 +3376,13 @@ var HostTimeApi = class {
3263
3376
  return response;
3264
3377
  }
3265
3378
  formatTime(timestamp, options) {
3266
- const locale = this.venusApi.getLocale();
3379
+ let locale = "en-US";
3380
+ const windowVenus = window.venus;
3381
+ if (windowVenus._config.locale) {
3382
+ locale = windowVenus._config.locale;
3383
+ } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3384
+ locale = windowVenus._config.environment.browserInfo.language;
3385
+ }
3267
3386
  const date = new Date(timestamp);
3268
3387
  const dateTimeOptions = {
3269
3388
  dateStyle: options.dateStyle || "medium",
@@ -3275,7 +3394,13 @@ var HostTimeApi = class {
3275
3394
  }
3276
3395
  formatNumber(value, options) {
3277
3396
  try {
3278
- const locale = this.venusApi.getLocale();
3397
+ let locale = "en-US";
3398
+ const windowVenus = window.venus;
3399
+ if (windowVenus._config.locale) {
3400
+ locale = windowVenus._config.locale;
3401
+ } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3402
+ locale = windowVenus._config.environment.browserInfo.language;
3403
+ }
3279
3404
  const numberOptions = {
3280
3405
  style: options?.style || "decimal",
3281
3406
  minimumFractionDigits: options?.minimumFractionDigits || 0,
@@ -3338,17 +3463,18 @@ var MockTimeApi = class {
3338
3463
  this.venusApi = venusApi;
3339
3464
  }
3340
3465
  formatNumber(value, options) {
3341
- const locale = this.venusApi.getLocale();
3466
+ const locale = this.getLocale();
3342
3467
  const numberOptions = {
3343
3468
  style: options?.style || "decimal",
3344
3469
  minimumFractionDigits: options?.minimumFractionDigits || 0,
3345
3470
  maximumFractionDigits: options?.maximumFractionDigits || 2,
3346
3471
  ...options
3347
3472
  };
3473
+ console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
3348
3474
  return value.toLocaleString(locale, numberOptions);
3349
3475
  }
3350
3476
  formatTime(timestamp, options) {
3351
- const locale = this.venusApi.getLocale();
3477
+ const locale = this.getLocale();
3352
3478
  const date = new Date(timestamp);
3353
3479
  const dateTimeOptions = {
3354
3480
  dateStyle: options.dateStyle || "medium",
@@ -3356,9 +3482,13 @@ var MockTimeApi = class {
3356
3482
  hour12: options.hour12 !== void 0 ? options.hour12 : true,
3357
3483
  ...options
3358
3484
  };
3485
+ console.log(
3486
+ `[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
3487
+ );
3359
3488
  return date.toLocaleString(locale, dateTimeOptions);
3360
3489
  }
3361
3490
  async getFutureTimeAsync(options) {
3491
+ console.log("[Venus Mock] Getting future time with options:", options);
3362
3492
  const timeInfo = await this.requestTimeAsync();
3363
3493
  const serverTime = new Date(timeInfo.serverTime);
3364
3494
  const result = new Date(serverTime);
@@ -3403,6 +3533,7 @@ var MockTimeApi = class {
3403
3533
  return result.getTime();
3404
3534
  }
3405
3535
  async requestTimeAsync() {
3536
+ console.log("[Venus Mock] Requesting time");
3406
3537
  await createMockDelay(MOCK_DELAYS.short);
3407
3538
  const venusApi = this.venusApi;
3408
3539
  const mockOffset = venusApi._mock.serverTimeOffset || 2500;
@@ -3416,8 +3547,23 @@ var MockTimeApi = class {
3416
3547
  formattedTime: new Date(localTime).toISOString(),
3417
3548
  locale: venusApi._mock.user?.locale || "en-US"
3418
3549
  };
3550
+ console.log("[Venus Mock] Time response:", {
3551
+ serverTime: new Date(timeInfo.serverTime).toISOString(),
3552
+ localTime: new Date(timeInfo.localTime).toISOString(),
3553
+ timezoneOffset: timeInfo.timezoneOffset
3554
+ });
3419
3555
  return timeInfo;
3420
3556
  }
3557
+ getLocale() {
3558
+ const venusApi = this.venusApi;
3559
+ let locale = "en-US";
3560
+ if (venusApi._mock.user && venusApi._mock.user.locale) {
3561
+ locale = venusApi._mock.user.locale;
3562
+ } else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
3563
+ locale = venusApi._mock.environment.browserInfo.language;
3564
+ }
3565
+ return locale;
3566
+ }
3421
3567
  };
3422
3568
 
3423
3569
  // src/time/index.ts
@@ -3437,176 +3583,11 @@ function initializeTime(venusApi, host) {
3437
3583
  }
3438
3584
 
3439
3585
  // src/version.ts
3440
- var SDK_VERSION = "3.1.2-beta.1";
3441
-
3442
- // src/shared-assets/embeddedLibrariesManifest.ts
3443
- var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
3444
- var EMBEDDED_LIBRARIES = [
3445
- {
3446
- libraryKey: "phaser@3.90.0",
3447
- assetKey: "library:phaser@3.90.0",
3448
- packageName: "phaser",
3449
- version: "3.90.0",
3450
- globalVar: "Phaser",
3451
- cdnPath: "phaser/3.90.0/phaser.min.js",
3452
- moduleSpecifiers: [{ match: "exact", value: "phaser" }],
3453
- loadStage: 0,
3454
- enabled: true
3455
- },
3456
- {
3457
- libraryKey: "react@18.3.1",
3458
- assetKey: "library:react@18.3.1",
3459
- packageName: "react",
3460
- version: "18.3.1",
3461
- globalVar: "React",
3462
- cdnPath: "react/18.3.1/react.production.min.js",
3463
- moduleSpecifiers: [
3464
- { match: "exact", value: "react", behavior: "namespace" },
3465
- { match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
3466
- {
3467
- match: "exact",
3468
- value: "react/jsx-dev-runtime",
3469
- behavior: "react-jsx-dev-runtime"
3470
- }
3471
- ],
3472
- loadStage: 0,
3473
- // Must load before ReactDOM
3474
- enabled: true
3475
- },
3476
- {
3477
- libraryKey: "react-dom@18.3.1",
3478
- assetKey: "library:react-dom@18.3.1",
3479
- packageName: "react-dom",
3480
- version: "18.3.1",
3481
- globalVar: "ReactDOM",
3482
- cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
3483
- moduleSpecifiers: [
3484
- { match: "exact", value: "react-dom", behavior: "namespace" },
3485
- { match: "exact", value: "react-dom/client", behavior: "namespace" }
3486
- ],
3487
- loadStage: 1,
3488
- // Depends on React (stage 0)
3489
- enabled: true
3490
- },
3491
- {
3492
- libraryKey: "three@0.170.0",
3493
- assetKey: "library:three@0.170.0",
3494
- packageName: "three",
3495
- version: "0.170.0",
3496
- globalVar: "THREE",
3497
- cdnPath: "three/r170/three.min.js",
3498
- moduleSpecifiers: [
3499
- { match: "exact", value: "three", behavior: "namespace" },
3500
- { match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
3501
- ],
3502
- loadStage: 0,
3503
- enabled: true
3504
- },
3505
- {
3506
- libraryKey: "matter-js@0.19.0",
3507
- assetKey: "library:matter-js@0.19.0",
3508
- packageName: "matter-js",
3509
- version: "0.19.0",
3510
- globalVar: "Matter",
3511
- cdnPath: "matter-js/0.19.0/matter.min.js",
3512
- moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
3513
- loadStage: 0,
3514
- enabled: true
3515
- },
3516
- {
3517
- libraryKey: "inkjs@2.2.0",
3518
- assetKey: "library:inkjs@2.2.0",
3519
- packageName: "inkjs",
3520
- version: "2.2.0",
3521
- globalVar: "inkjs",
3522
- cdnPath: "inkjs/2.2.0/ink.min.js",
3523
- moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
3524
- loadStage: 0,
3525
- enabled: true
3526
- },
3527
- {
3528
- libraryKey: "zustand@5.0.3",
3529
- assetKey: "library:zustand@5.0.3",
3530
- packageName: "zustand",
3531
- version: "5.0.3",
3532
- globalVar: "zustand",
3533
- cdnPath: "zustand/5.0.3/zustand.min.js",
3534
- moduleSpecifiers: [
3535
- { match: "exact", value: "zustand" },
3536
- { match: "exact", value: "zustand/middleware" }
3537
- ],
3538
- loadStage: 0,
3539
- enabled: true
3540
- },
3541
- {
3542
- libraryKey: "ammo.js@2024.11",
3543
- assetKey: "library:ammo.js@2024.11",
3544
- packageName: "ammo.js",
3545
- version: "2024.11",
3546
- globalVar: "Ammo",
3547
- cdnPath: "ammo/2024.11/ammo.js",
3548
- moduleSpecifiers: [
3549
- { match: "exact", value: "ammo.js" },
3550
- { match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
3551
- ],
3552
- loadStage: 0,
3553
- enabled: false
3554
- // Not ready yet - WASM loading needs additional work
3555
- }
3556
- ];
3557
- var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
3558
- (acc, lib) => {
3559
- acc[lib.libraryKey] = lib;
3560
- return acc;
3561
- },
3562
- {}
3563
- );
3564
- var MODULE_TO_LIBRARY_SPECIFIERS = EMBEDDED_LIBRARIES.filter(
3565
- (lib) => lib.enabled
3566
- ).flatMap(
3567
- (lib) => lib.moduleSpecifiers.map((specifier) => ({
3568
- ...specifier,
3569
- libraryKey: lib.libraryKey
3570
- }))
3571
- );
3572
- function getLibraryDefinition(libraryKey) {
3573
- const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
3574
- if (!definition) {
3575
- const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
3576
- throw new Error(
3577
- `Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
3578
- );
3579
- }
3580
- return definition;
3581
- }
3586
+ var SDK_VERSION = "3.0.4";
3582
3587
 
3583
- // src/shared-assets/base64Utils.ts
3584
- function base64ToArrayBuffer(base64) {
3585
- const binaryString = atob(base64);
3586
- const len = binaryString.length;
3587
- const bytes = new Uint8Array(len);
3588
- for (let i = 0; i < len; i++) {
3589
- bytes[i] = binaryString.charCodeAt(i);
3590
- }
3591
- return bytes.buffer;
3592
- }
3593
- function base64ToUtf8(base64) {
3594
- if (typeof TextDecoder !== "undefined") {
3595
- const decoder = new TextDecoder("utf-8");
3596
- const buffer = base64ToArrayBuffer(base64);
3597
- return decoder.decode(new Uint8Array(buffer));
3598
- }
3599
- if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
3600
- const BufferCtor = globalThis.Buffer;
3601
- return BufferCtor.from(base64, "base64").toString("utf-8");
3602
- }
3603
- const binaryString = atob(base64);
3604
- let result = "";
3605
- for (let i = 0; i < binaryString.length; i++) {
3606
- result += String.fromCharCode(binaryString.charCodeAt(i));
3607
- }
3608
- return decodeURIComponent(escape(result));
3609
- }
3588
+ // src/shared-assets/consts.ts
3589
+ var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
3590
+ var CharacterAssetsCdnPath = "burger-time/Character.stow";
3610
3591
 
3611
3592
  // src/shared-assets/RpcSharedAssetsApi.ts
3612
3593
  var RpcSharedAssetsApi = class {
@@ -3616,48 +3597,46 @@ var RpcSharedAssetsApi = class {
3616
3597
  this.rpcClient = rpcClient;
3617
3598
  this.venusApi = venusApi;
3618
3599
  }
3619
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3600
+ async loadBurgerTimeAssetsBundle() {
3620
3601
  try {
3621
3602
  const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3622
- assetKey: bundleKey
3603
+ assetKey: "burgerTimeCoreBundle"
3623
3604
  });
3624
3605
  return base64ToArrayBuffer(response.base64Data);
3625
3606
  } catch (err) {
3626
3607
  try {
3627
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3608
+ const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
3628
3609
  return await blob.arrayBuffer();
3629
3610
  } catch (e) {
3630
- throw new Error(`Failed to load ${bundleKey}`);
3611
+ throw new Error("Failed to load burgerTimeAssetsBundle");
3631
3612
  }
3632
3613
  }
3633
3614
  }
3634
- async loadLibraryCode(libraryKey) {
3635
- const definition = getLibraryDefinition(libraryKey);
3615
+ async loadCharactersBundle() {
3636
3616
  try {
3637
3617
  const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3638
- assetKey: definition.assetKey
3618
+ assetKey: "characters"
3639
3619
  });
3640
- return base64ToUtf8(response.base64Data);
3620
+ return base64ToArrayBuffer(response.base64Data);
3641
3621
  } catch (err) {
3642
- console.error(
3643
- `[Venus Libraries] Failed to load ${libraryKey} from host via RPC:`,
3644
- err
3645
- );
3646
- console.warn(
3647
- `[Venus Libraries] Falling back to CDN for ${libraryKey}. This may indicate an asset packaging issue.`
3648
- );
3649
3622
  try {
3650
- const cdnUrl = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3651
- const response = await this.venusApi.cdn.fetchFromCdn(cdnUrl);
3652
- return await response.text();
3653
- } catch (cdnError) {
3654
- throw new Error(
3655
- `Failed to load embedded library ${libraryKey}: RPC failed, CDN fallback failed: ${cdnError.message}`
3656
- );
3623
+ const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
3624
+ return await blob.arrayBuffer();
3625
+ } catch (e) {
3626
+ throw new Error("Failed to load charactersBundle");
3657
3627
  }
3658
3628
  }
3659
3629
  }
3660
3630
  };
3631
+ function base64ToArrayBuffer(base64) {
3632
+ const binaryString = atob(base64);
3633
+ const len = binaryString.length;
3634
+ const bytes = new Uint8Array(len);
3635
+ for (let i = 0; i < len; i++) {
3636
+ bytes[i] = binaryString.charCodeAt(i);
3637
+ }
3638
+ return bytes.buffer;
3639
+ }
3661
3640
 
3662
3641
  // src/shared-assets/MockSharedAssetsApi.ts
3663
3642
  var MockSharedAssetsApi = class {
@@ -3665,118 +3644,57 @@ var MockSharedAssetsApi = class {
3665
3644
  __publicField(this, "venusApi");
3666
3645
  this.venusApi = venusApi;
3667
3646
  }
3668
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3669
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3647
+ async loadBurgerTimeAssetsBundle() {
3648
+ const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
3670
3649
  return await blob.arrayBuffer();
3671
3650
  }
3672
- async loadLibraryCode(libraryKey) {
3673
- const definition = getLibraryDefinition(libraryKey);
3674
- const url = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3675
- const response = await this.venusApi.cdn.fetchFromCdn(url);
3676
- return await response.text();
3651
+ async loadCharactersBundle() {
3652
+ const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
3653
+ return await blob.arrayBuffer();
3677
3654
  }
3678
3655
  };
3679
3656
 
3680
- // src/leaderboard/utils.ts
3681
- var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
3682
- var HASH_ALGORITHM_NODE = "sha256";
3683
- async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
3684
- const payload = `score:${score}|duration:${duration}|token:${token}`;
3685
- const fullPayload = `${payload}|nonce:${sealingNonce}`;
3686
- const encoder = new TextEncoder();
3687
- const keyData = encoder.encode(sealingSecret);
3688
- const messageData = encoder.encode(fullPayload);
3689
- const cryptoKey = await crypto.subtle.importKey(
3690
- "raw",
3691
- keyData,
3692
- { name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
3693
- false,
3694
- ["sign"]
3695
- );
3696
- const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
3697
- return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
3698
- }
3699
-
3700
3657
  // src/leaderboard/RpcLeaderboardApi.ts
3701
3658
  var RpcLeaderboardApi = class {
3702
3659
  constructor(rpcClient) {
3703
3660
  __publicField(this, "rpcClient");
3704
- /** Cache of score tokens for automatic hash computation */
3705
- __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3706
3661
  this.rpcClient = rpcClient;
3707
3662
  }
3708
- /**
3709
- * Create a score token for submitting a score.
3710
- * Token is cached for automatic hash computation if score sealing is enabled.
3711
- *
3712
- * @param mode - Optional game mode
3713
- * @returns Score token with sealing data if enabled
3714
- */
3715
- async createScoreToken(mode) {
3716
- const token = await this.rpcClient.call(
3717
- "H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
3663
+ startRun(mode) {
3664
+ return this.rpcClient.call(
3665
+ "H5_LEADERBOARD_START_RUN" /* H5_LEADERBOARD_START_RUN */,
3718
3666
  mode ? { mode } : {}
3719
3667
  );
3720
- this.tokenCache.set(token.token, token);
3721
- return token;
3722
3668
  }
3723
- /**
3724
- * Submit a score to the leaderboard.
3725
- * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3726
- *
3727
- * @param params - Score submission parameters
3728
- * @returns Submission result with acceptance status and rank
3729
- * @throws Error if token not found in cache
3730
- */
3731
- async submitScore(params) {
3732
- let hash;
3733
- if (params.token) {
3734
- const cachedToken = this.tokenCache.get(params.token);
3735
- if (!cachedToken) {
3736
- throw new Error(
3737
- "Invalid token: not found in cache. Did you call createScoreToken() first?"
3738
- );
3739
- }
3740
- if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3741
- hash = await computeScoreHash(
3742
- params.score,
3743
- params.duration,
3744
- params.token,
3745
- cachedToken.sealingNonce,
3746
- cachedToken.sealingSecret
3747
- );
3748
- }
3749
- this.tokenCache.delete(params.token);
3750
- }
3669
+ submitScore(sessionId, score, durationSec, options) {
3751
3670
  return this.rpcClient.call(
3752
3671
  "H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
3753
3672
  {
3754
- token: params.token,
3755
- score: params.score,
3756
- duration: params.duration,
3757
- mode: params.mode,
3758
- telemetry: params.telemetry,
3759
- metadata: params.metadata,
3760
- hash
3761
- // undefined if no sealing, computed if sealing enabled
3673
+ sessionId,
3674
+ score,
3675
+ durationSec,
3676
+ mode: options?.mode,
3677
+ telemetry: options?.telemetry,
3678
+ metadata: options?.metadata,
3679
+ hash: options?.hash
3762
3680
  }
3763
3681
  );
3764
3682
  }
3765
- getPagedScores(options) {
3683
+ getLeaderboard(options) {
3766
3684
  return this.rpcClient.call(
3767
- "H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
3685
+ "H5_LEADERBOARD_GET" /* H5_LEADERBOARD_GET */,
3768
3686
  options ?? {}
3769
3687
  );
3770
3688
  }
3771
- getMyRank(options) {
3689
+ getPlayerStats(options) {
3772
3690
  return this.rpcClient.call(
3773
- "H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
3691
+ "H5_LEADERBOARD_GET_PLAYER_STATS" /* H5_LEADERBOARD_GET_PLAYER_STATS */,
3774
3692
  options ?? {}
3775
3693
  );
3776
3694
  }
3777
- getPodiumScores(options) {
3695
+ getLeaderboardHighlight(options) {
3778
3696
  return this.rpcClient.call(
3779
- "H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
3697
+ "H5_LEADERBOARD_GET_HIGHLIGHT" /* H5_LEADERBOARD_GET_HIGHLIGHT */,
3780
3698
  options ?? {}
3781
3699
  );
3782
3700
  }
@@ -3785,31 +3703,17 @@ var RpcLeaderboardApi = class {
3785
3703
  // src/leaderboard/MockLeaderboardApi.ts
3786
3704
  var MockLeaderboardApi = class {
3787
3705
  constructor(options) {
3788
- __publicField(this, "tokens", /* @__PURE__ */ new Map());
3789
- /** Cache of score tokens for automatic hash computation */
3790
- __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3706
+ __publicField(this, "sessions", /* @__PURE__ */ new Map());
3791
3707
  __publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
3792
- __publicField(this, "tokenCounter", 0);
3793
- __publicField(this, "enableScoreSealing", false);
3794
- __publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
3795
- if (options?.enableScoreSealing) {
3796
- this.enableScoreSealing = true;
3797
- }
3798
- if (options?.scoreSealingSecret) {
3799
- this.scoreSealingSecret = options.scoreSealingSecret;
3708
+ __publicField(this, "sessionCounter", 0);
3709
+ __publicField(this, "requiresHash", false);
3710
+ if (options?.requiresHash) {
3711
+ this.requiresHash = true;
3800
3712
  }
3801
3713
  }
3802
- /**
3803
- * Configure mock leaderboard settings
3804
- *
3805
- * @param options - Configuration options
3806
- */
3807
3714
  configure(options) {
3808
- if (typeof options.enableScoreSealing === "boolean") {
3809
- this.enableScoreSealing = options.enableScoreSealing;
3810
- }
3811
- if (options.scoreSealingSecret) {
3812
- this.scoreSealingSecret = options.scoreSealingSecret;
3715
+ if (typeof options.requiresHash === "boolean") {
3716
+ this.requiresHash = options.requiresHash;
3813
3717
  }
3814
3718
  }
3815
3719
  generateNonce() {
@@ -3826,149 +3730,83 @@ var MockLeaderboardApi = class {
3826
3730
  }
3827
3731
  return this.entriesByMode.get(key);
3828
3732
  }
3829
- /**
3830
- * Create a mock score token for testing.
3831
- * Token is cached for automatic hash computation if score sealing is enabled.
3832
- *
3833
- * @param mode - Optional game mode
3834
- * @returns Score token with sealing data if enabled
3835
- */
3836
- async createScoreToken(mode) {
3837
- const token = `mock_token_${++this.tokenCounter}`;
3733
+ async startRun(mode) {
3734
+ const sessionId = `mock_session_${++this.sessionCounter}`;
3838
3735
  const startTime = Date.now();
3839
3736
  const expiresAt = startTime + 36e5;
3840
3737
  const resolvedMode = mode || "default";
3841
- const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
3842
- const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
3843
- this.tokens.set(token, {
3844
- id: token,
3738
+ const hashNonce = this.requiresHash ? this.generateNonce() : null;
3739
+ this.sessions.set(sessionId, {
3740
+ id: sessionId,
3845
3741
  expiresAt,
3846
3742
  mode: resolvedMode,
3847
- sealingNonce,
3743
+ hashNonce,
3848
3744
  used: false
3849
3745
  });
3850
- const result = {
3851
- token,
3746
+ return {
3747
+ sessionId,
3852
3748
  startTime,
3853
3749
  expiresAt,
3854
- sealingNonce,
3855
- sealingSecret,
3750
+ hashNonce,
3856
3751
  mode: resolvedMode
3857
3752
  };
3858
- this.tokenCache.set(token, result);
3859
- return result;
3860
3753
  }
3861
- /**
3862
- * Submit a mock score to the leaderboard.
3863
- * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3864
- *
3865
- * @param params - Score submission parameters
3866
- * @returns Submission result with acceptance status and rank
3867
- * @throws Error if token not found in cache or validation fails
3868
- */
3869
- async submitScore(params) {
3870
- let hash;
3871
- if (params.token) {
3872
- const cachedToken = this.tokenCache.get(params.token);
3873
- if (!cachedToken) {
3874
- throw new Error(
3875
- "Invalid token: not found in cache. Did you call createScoreToken() first?"
3876
- );
3877
- }
3878
- if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3879
- hash = await computeScoreHash(
3880
- params.score,
3881
- params.duration,
3882
- params.token,
3883
- cachedToken.sealingNonce,
3884
- cachedToken.sealingSecret
3885
- );
3886
- }
3887
- }
3888
- if (!params.token) {
3889
- const mode = params.mode || "default";
3890
- const submittedAt2 = Date.now();
3891
- const entry2 = {
3892
- profileId: `mock_profile`,
3893
- username: "Mock Player",
3894
- avatarUrl: null,
3895
- score: params.score,
3896
- duration: params.duration,
3897
- submittedAt: submittedAt2,
3898
- token: "simple-mode",
3899
- rank: null,
3900
- zScore: null,
3901
- isAnomaly: false,
3902
- trustScore: 50,
3903
- metadata: params.metadata ?? null,
3904
- isSeed: false
3905
- };
3906
- const modeEntries2 = this.getEntriesForMode(mode);
3907
- modeEntries2.push(entry2);
3908
- modeEntries2.sort((a, b) => {
3909
- if (b.score !== a.score) return b.score - a.score;
3910
- return a.submittedAt - b.submittedAt;
3911
- });
3912
- modeEntries2.forEach((e, index) => {
3913
- modeEntries2[index] = { ...e, rank: index + 1 };
3914
- });
3915
- const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
3916
- return {
3917
- accepted: true,
3918
- rank: inserted2?.rank ?? null
3919
- };
3920
- }
3921
- const scoreToken = this.tokens.get(params.token);
3922
- if (!scoreToken) {
3923
- throw new Error("Invalid score token");
3754
+ async submitScore(sessionId, score, durationSec, options) {
3755
+ const session = this.sessions.get(sessionId);
3756
+ if (!session) {
3757
+ throw new Error("Invalid leaderboard session");
3924
3758
  }
3925
- if (scoreToken.expiresAt < Date.now()) {
3926
- throw new Error("Invalid or expired score token");
3759
+ if (session.expiresAt < Date.now()) {
3760
+ throw new Error("Invalid or expired leaderboard session");
3927
3761
  }
3928
- if (scoreToken.used) {
3929
- throw new Error("Score token already used");
3762
+ if (session.used) {
3763
+ throw new Error("Leaderboard session already used");
3930
3764
  }
3931
- if (params.mode && params.mode !== scoreToken.mode) {
3932
- throw new Error("Submission mode does not match token mode");
3765
+ if (options?.mode && options.mode !== session.mode) {
3766
+ throw new Error("Submission mode does not match session mode");
3933
3767
  }
3934
- if (scoreToken.sealingNonce && !hash) {
3935
- throw new Error("Score hash required when score sealing is enabled");
3768
+ if (session.hashNonce && !options?.hash) {
3769
+ throw new Error("Score hash is required for sealed leaderboard submissions");
3936
3770
  }
3937
3771
  const submittedAt = Date.now();
3938
3772
  const entry = {
3939
3773
  profileId: `mock_profile`,
3940
3774
  username: "Mock Player",
3941
3775
  avatarUrl: null,
3942
- score: params.score,
3943
- duration: params.duration,
3776
+ score,
3777
+ durationSec,
3944
3778
  submittedAt,
3945
- token: params.token,
3779
+ sessionId,
3946
3780
  rank: null,
3947
3781
  zScore: null,
3948
3782
  isAnomaly: false,
3949
3783
  trustScore: 50,
3950
- metadata: params.metadata ?? null,
3784
+ metadata: options?.metadata ?? null,
3951
3785
  isSeed: false
3952
3786
  };
3953
- const modeEntries = this.getEntriesForMode(scoreToken.mode);
3787
+ const modeEntries = this.getEntriesForMode(session.mode);
3954
3788
  modeEntries.push(entry);
3955
3789
  modeEntries.sort((a, b) => {
3956
- if (b.score !== a.score) return b.score - a.score;
3790
+ if (b.score !== a.score) {
3791
+ return b.score - a.score;
3792
+ }
3957
3793
  return a.submittedAt - b.submittedAt;
3958
3794
  });
3959
3795
  modeEntries.forEach((e, index) => {
3960
- modeEntries[index] = { ...e, rank: index + 1 };
3796
+ modeEntries[index] = {
3797
+ ...e,
3798
+ rank: index + 1
3799
+ };
3961
3800
  });
3962
- scoreToken.used = true;
3963
- scoreToken.sealingNonce = null;
3964
- this.tokenCache.delete(params.token);
3965
- const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
3801
+ session.used = true;
3802
+ session.hashNonce = null;
3803
+ const inserted = modeEntries.find((e) => e.sessionId === sessionId && e.submittedAt === submittedAt);
3966
3804
  return {
3967
3805
  accepted: true,
3968
3806
  rank: inserted?.rank ?? null
3969
3807
  };
3970
3808
  }
3971
- async getPagedScores(options) {
3809
+ async getLeaderboard(options) {
3972
3810
  const limit = options?.limit ?? 10;
3973
3811
  const mode = options?.mode ?? "default";
3974
3812
  const modeEntries = [...this.getEntriesForMode(mode)];
@@ -3984,7 +3822,7 @@ var MockLeaderboardApi = class {
3984
3822
  periodInstance: options?.period ?? "alltime"
3985
3823
  };
3986
3824
  }
3987
- async getMyRank(_options) {
3825
+ async getPlayerStats(_options) {
3988
3826
  const mode = _options?.mode ?? "default";
3989
3827
  const modeEntries = this.getEntriesForMode(mode);
3990
3828
  const playerEntry = modeEntries[0] ?? null;
@@ -3997,7 +3835,7 @@ var MockLeaderboardApi = class {
3997
3835
  periodInstance: _options?.period ?? "alltime"
3998
3836
  };
3999
3837
  }
4000
- async getPodiumScores(options) {
3838
+ async getLeaderboardHighlight(options) {
4001
3839
  const mode = options?.mode ?? "default";
4002
3840
  const modeEntries = [...this.getEntriesForMode(mode)];
4003
3841
  const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
@@ -4070,24 +3908,100 @@ var RpcPreloaderApi = class {
4070
3908
  __publicField(this, "rpcClient");
4071
3909
  this.rpcClient = rpcClient;
4072
3910
  }
4073
- async showLoadScreen() {
4074
- await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
3911
+ async showLoadScreen() {
3912
+ await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
3913
+ }
3914
+ async hideLoadScreen() {
3915
+ await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
3916
+ }
3917
+ async setLoaderText(text) {
3918
+ await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
3919
+ }
3920
+ async setLoaderProgress(progress) {
3921
+ await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
3922
+ }
3923
+ };
3924
+
3925
+ // src/game-preloader/index.ts
3926
+ function initializePreloader(venusApi, host) {
3927
+ venusApi.preloader = host.preloader;
3928
+ }
3929
+
3930
+ // src/post/MockPostApi.ts
3931
+ var MockPostApi = class {
3932
+ constructor(venusApi) {
3933
+ __publicField(this, "venusApi");
3934
+ this.venusApi = venusApi;
3935
+ }
3936
+ async getPostInfo() {
3937
+ const venusApi = this.venusApi;
3938
+ await createMockDelay(MOCK_DELAYS.short);
3939
+ return venusApi._mock.currentPostInteractions;
3940
+ }
3941
+ async openCommentsAsync() {
3942
+ await createMockDelay(MOCK_DELAYS.short);
3943
+ return {
3944
+ opened: true,
3945
+ commentsCount: 0
3946
+ };
3947
+ }
3948
+ async toggleFollowAsync() {
3949
+ const venusApi = this.venusApi;
3950
+ console.log("[Venus Mock] *Toggling follow status");
3951
+ await createMockDelay(MOCK_DELAYS.short);
3952
+ venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
3953
+ const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
3954
+ return {
3955
+ isFollowing,
3956
+ action: isFollowing ? "followed" : "unfollowed"
3957
+ };
3958
+ }
3959
+ async toggleLikeAsync() {
3960
+ const venusApi = this.venusApi;
3961
+ await createMockDelay(MOCK_DELAYS.short);
3962
+ venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
3963
+ const isLiked = venusApi._mock.currentPostInteractions.isLiked;
3964
+ if (isLiked) {
3965
+ venusApi._mock.currentPostInteractions.likesCount++;
3966
+ } else {
3967
+ venusApi._mock.currentPostInteractions.likesCount = Math.max(
3968
+ 0,
3969
+ venusApi._mock.currentPostInteractions.likesCount - 1
3970
+ );
3971
+ }
3972
+ return {
3973
+ isLiked,
3974
+ likesCount: venusApi._mock.currentPostInteractions.likesCount,
3975
+ action: isLiked ? "liked" : "unliked"
3976
+ };
3977
+ }
3978
+ };
3979
+
3980
+ // src/post/RpcPostApi.ts
3981
+ var RpcPostApi = class {
3982
+ constructor(rpcClient) {
3983
+ __publicField(this, "rpcClient");
3984
+ this.rpcClient = rpcClient;
3985
+ }
3986
+ getPostInfo() {
3987
+ return this.rpcClient.call("H5_GET_POST_INTERACTIONS" /* GET_POST_INTERACTIONS */, {});
4075
3988
  }
4076
- async hideLoadScreen() {
4077
- await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
3989
+ openCommentsAsync() {
3990
+ return this.rpcClient.call("H5_OPEN_COMMENTS" /* OPEN_COMMENTS */, {});
4078
3991
  }
4079
- async setLoaderText(text) {
4080
- await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
3992
+ toggleFollowAsync() {
3993
+ return this.rpcClient.call(
3994
+ "H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
3995
+ {}
3996
+ );
4081
3997
  }
4082
- async setLoaderProgress(progress) {
4083
- await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
3998
+ toggleLikeAsync() {
3999
+ return this.rpcClient.call("H5_TOGGLE_LIKE" /* TOGGLE_LIKE */, {});
4084
4000
  }
4085
4001
  };
4086
4002
 
4087
- // src/game-preloader/index.ts
4088
- function initializePreloader(venusApi, host) {
4089
- venusApi.preloader = host.preloader;
4090
- }
4003
+ // src/MockHost.ts
4004
+ init_rooms();
4091
4005
 
4092
4006
  // src/social/MockSocialApi.ts
4093
4007
  var MOCK_QR_CODE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
@@ -4125,116 +4039,44 @@ var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when ru
4125
4039
  function createUnavailableRoomsApi() {
4126
4040
  const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
4127
4041
  return {
4128
- async createRoomAsync() {
4042
+ async createRoom() {
4129
4043
  throw roomsUnavailableError();
4130
4044
  },
4131
- async joinOrCreateRoomAsync() {
4045
+ async joinOrCreateRoom() {
4132
4046
  throw roomsUnavailableError();
4133
4047
  },
4134
- async joinRoomByCodeAsync() {
4048
+ async getUserRooms() {
4135
4049
  throw roomsUnavailableError();
4136
4050
  },
4137
- async getUserRoomsAsync() {
4051
+ async joinRoomByCode() {
4138
4052
  throw roomsUnavailableError();
4139
4053
  },
4140
- async subscribeAsync() {
4054
+ subscribe() {
4141
4055
  throw roomsUnavailableError();
4142
4056
  },
4143
- async updateRoomDataAsync() {
4057
+ async updateData() {
4144
4058
  throw roomsUnavailableError();
4145
4059
  },
4146
- async getRoomDataAsync() {
4060
+ async getData() {
4147
4061
  throw roomsUnavailableError();
4148
4062
  },
4149
- async sendRoomMessageAsync() {
4063
+ async sendMessage() {
4150
4064
  throw roomsUnavailableError();
4151
4065
  },
4152
- async leaveRoomAsync() {
4066
+ async leave() {
4153
4067
  throw roomsUnavailableError();
4154
4068
  },
4155
- async startRoomGameAsync() {
4069
+ async startGame() {
4156
4070
  throw roomsUnavailableError();
4157
4071
  },
4158
- async proposeMoveAsync() {
4072
+ async proposeMove() {
4159
4073
  throw roomsUnavailableError();
4160
4074
  },
4161
- async validateMoveAsync() {
4075
+ async validateMove() {
4162
4076
  throw roomsUnavailableError();
4163
4077
  }
4164
4078
  };
4165
4079
  }
4166
- var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
4167
- function createUnavailableSimulationApi() {
4168
- const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
4169
- return {
4170
- isEnabled() {
4171
- return false;
4172
- },
4173
- async getStateAsync() {
4174
- throw simulationUnavailableError();
4175
- },
4176
- async getConfigAsync() {
4177
- throw simulationUnavailableError();
4178
- },
4179
- async executeRecipeAsync() {
4180
- throw simulationUnavailableError();
4181
- },
4182
- async getActiveRunsAsync() {
4183
- throw simulationUnavailableError();
4184
- },
4185
- async collectRecipeAsync() {
4186
- throw simulationUnavailableError();
4187
- },
4188
- async executeScopedRecipeAsync() {
4189
- throw simulationUnavailableError();
4190
- },
4191
- async triggerRecipeChainAsync() {
4192
- throw simulationUnavailableError();
4193
- },
4194
- async getAvailableRecipesAsync() {
4195
- throw simulationUnavailableError();
4196
- },
4197
- async getRecipeRequirementsAsync() {
4198
- throw simulationUnavailableError();
4199
- },
4200
- async getBatchRecipeRequirementsAsync() {
4201
- throw simulationUnavailableError();
4202
- },
4203
- async resolveFieldValueAsync() {
4204
- throw simulationUnavailableError();
4205
- },
4206
- async getEntityMetadataAsync() {
4207
- throw simulationUnavailableError();
4208
- },
4209
- async getSlotContainersAsync() {
4210
- throw simulationUnavailableError();
4211
- },
4212
- async getSlotAssignmentsAsync() {
4213
- throw simulationUnavailableError();
4214
- },
4215
- async assignItemToSlotAsync() {
4216
- throw simulationUnavailableError();
4217
- },
4218
- async removeItemFromSlotAsync() {
4219
- throw simulationUnavailableError();
4220
- },
4221
- async getAvailableItemsAsync() {
4222
- throw simulationUnavailableError();
4223
- },
4224
- async calculatePowerPreviewAsync() {
4225
- throw simulationUnavailableError();
4226
- },
4227
- async validateSlotAssignmentAsync() {
4228
- throw simulationUnavailableError();
4229
- },
4230
- async executeBatchOperationsAsync() {
4231
- throw simulationUnavailableError();
4232
- },
4233
- async subscribeAsync() {
4234
- throw simulationUnavailableError();
4235
- }
4236
- };
4237
- }
4238
4080
  var MockHost = class {
4239
4081
  constructor(venusApi) {
4240
4082
  __publicField(this, "ads");
@@ -4247,9 +4089,9 @@ var MockHost = class {
4247
4089
  __publicField(this, "notifications");
4248
4090
  __publicField(this, "popups");
4249
4091
  __publicField(this, "profile");
4250
- __publicField(this, "system");
4251
4092
  __publicField(this, "cdn");
4252
4093
  __publicField(this, "time");
4094
+ __publicField(this, "post");
4253
4095
  __publicField(this, "ai");
4254
4096
  __publicField(this, "haptics");
4255
4097
  __publicField(this, "features");
@@ -4281,17 +4123,15 @@ var MockHost = class {
4281
4123
  this.navigation = new MockNavigationApi(venusApi);
4282
4124
  this.notifications = new MockNotificationsApi(venusApi);
4283
4125
  this.popups = new MockPopupsApi(this._overlay);
4284
- this.profile = new MockProfileApi(venusApi);
4285
- const deviceApi = new MockDeviceApi(venusApi);
4286
- const environmentApi = new MockEnvironmentApi(venusApi);
4287
- this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
4288
- this.cdn = new MockCdnApi(venusApi);
4126
+ this.profile = new MockProfileApi();
4127
+ this.cdn = new MockCdnApi();
4289
4128
  this.time = new MockTimeApi(venusApi);
4129
+ this.post = new MockPostApi(venusApi);
4290
4130
  this.ai = new MockAiApi();
4291
4131
  this.haptics = new MockHapticsApi(venusApi);
4292
4132
  this.features = new MockFeaturesApi();
4293
4133
  this.lifecycle = this._mockLifecyclesApi;
4294
- this.simulation = createUnavailableSimulationApi();
4134
+ this.simulation = new MockSimulationApi();
4295
4135
  this.rooms = createUnavailableRoomsApi();
4296
4136
  this.logging = new MockLoggingApi();
4297
4137
  this.iap = new MockIapApi();
@@ -4307,17 +4147,40 @@ var MockHost = class {
4307
4147
  }
4308
4148
  initialize(options) {
4309
4149
  this._isInitialized = true;
4310
- this.venusApi._profileData = this.profile.getCurrentProfile();
4311
- this.venusApi._deviceData = this.system.getDevice();
4312
- this.venusApi._environmentData = this.system.getEnvironment();
4313
- this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
4314
- this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
4150
+ const controls = this.updateUiControls();
4315
4151
  return Promise.resolve({
4316
4152
  initializeAsleep: false,
4317
- safeArea: this.venusApi._safeAreaData
4153
+ hudInsets: {
4154
+ top: controls.feedHeader.height,
4155
+ bottom: 0,
4156
+ left: 0,
4157
+ right: 0
4158
+ }
4318
4159
  });
4319
4160
  }
4161
+ updateUiControls() {
4162
+ const controls = {
4163
+ closeButton: { x: 16, y: 16, width: 32, height: 32 },
4164
+ menuButton: {
4165
+ x: window.innerWidth - 48,
4166
+ y: 16,
4167
+ width: 32,
4168
+ height: 32
4169
+ },
4170
+ feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
4171
+ playButton: {
4172
+ x: 0,
4173
+ y: window.innerHeight - 60,
4174
+ width: window.innerWidth,
4175
+ height: 60
4176
+ }
4177
+ };
4178
+ return controls;
4179
+ }
4320
4180
  createOverlay() {
4181
+ const venusApi = this.venusApi;
4182
+ venusApi.config.ui.controls = this.updateUiControls();
4183
+ const uiControls = venusApi.config.ui.controls;
4321
4184
  const overlayContainer = document.createElement("div");
4322
4185
  overlayContainer.id = "venus-mock-overlay";
4323
4186
  overlayContainer.style.cssText = `
@@ -4333,7 +4196,7 @@ var MockHost = class {
4333
4196
  const menuButton = this.createOverlayButton(
4334
4197
  "close",
4335
4198
  "Menu",
4336
- { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
4199
+ uiControls.menuButton,
4337
4200
  () => {
4338
4201
  this.handleMenuButtonClicked();
4339
4202
  },
@@ -4562,13 +4425,17 @@ var MockHost = class {
4562
4425
  return button;
4563
4426
  }
4564
4427
  updateOverlayLayout() {
4428
+ const venusApi = this.venusApi;
4565
4429
  const overlay = this._overlay;
4430
+ venusApi.config.ui.controls = this.updateUiControls();
4431
+ const uiControls = venusApi.config.ui.controls;
4566
4432
  const menuBtn = overlay.elements.menuButton;
4567
- menuBtn.style.left = `${window.innerWidth - 48}px`;
4568
- menuBtn.style.top = "16px";
4569
- menuBtn.style.width = "32px";
4570
- menuBtn.style.minWidth = "32px";
4571
- menuBtn.style.height = "32px";
4433
+ const menuPos = uiControls.menuButton;
4434
+ menuBtn.style.left = `${menuPos.x}px`;
4435
+ menuBtn.style.top = `${menuPos.y}px`;
4436
+ menuBtn.style.width = `${menuPos.width}px`;
4437
+ menuBtn.style.minWidth = `${menuPos.width}px`;
4438
+ menuBtn.style.height = `${menuPos.height}px`;
4572
4439
  }
4573
4440
  triggerLifecycleEvent(name) {
4574
4441
  console.log("Trigger Lifecycle Event: ", name);
@@ -4797,16 +4664,6 @@ var VenusTransport = class {
4797
4664
  this.isProcessingMessage = false;
4798
4665
  return;
4799
4666
  }
4800
- if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
4801
- const notification = {
4802
- type: "rpc-notification",
4803
- id: message.type,
4804
- payload: message.data
4805
- };
4806
- this.handleNotification(notification);
4807
- this.isProcessingMessage = false;
4808
- return;
4809
- }
4810
4667
  const requestId = messageData.requestId;
4811
4668
  if (!requestId) {
4812
4669
  this.logWarn("No requestId. Ignoring message...");
@@ -4973,6 +4830,294 @@ var VenusTransport = class {
4973
4830
  }
4974
4831
  };
4975
4832
 
4833
+ // src/RemoteHost.ts
4834
+ init_rooms();
4835
+
4836
+ // src/rooms/RpcRoomsApi.ts
4837
+ init_VenusRoom();
4838
+ var RpcRoomsApi = class {
4839
+ constructor(rpcClient) {
4840
+ __publicField(this, "rpcClient");
4841
+ __publicField(this, "subscriptions");
4842
+ __publicField(this, "transportSubscription", null);
4843
+ this.rpcClient = rpcClient;
4844
+ this.subscriptions = {
4845
+ data: {},
4846
+ messages: {},
4847
+ gameEvents: {},
4848
+ allEvents: {}
4849
+ };
4850
+ }
4851
+ /**
4852
+ * Get the subscription state for external access (used by setupRoomNotifications)
4853
+ */
4854
+ getSubscriptions() {
4855
+ return this.subscriptions;
4856
+ }
4857
+ /**
4858
+ * Set up room notification routing from the transport
4859
+ */
4860
+ setupNotifications(transport) {
4861
+ const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
4862
+ this.transportSubscription = setupRoomNotifications2(
4863
+ transport,
4864
+ () => this.getSubscriptions()
4865
+ );
4866
+ }
4867
+ /**
4868
+ * Clean up subscriptions and resources
4869
+ */
4870
+ dispose() {
4871
+ if (this.transportSubscription) {
4872
+ this.transportSubscription.unsubscribe();
4873
+ this.transportSubscription = null;
4874
+ console.log("[Venus Rooms] Cleaned up room notification subscription");
4875
+ }
4876
+ }
4877
+ async createRoom(options) {
4878
+ const response = await this.rpcClient.call(
4879
+ "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
4880
+ {
4881
+ options
4882
+ }
4883
+ );
4884
+ if (response.success === false) {
4885
+ throw new Error(response.error || "Failed to create room");
4886
+ }
4887
+ const roomData = response.roomData || response;
4888
+ const room = new exports.VenusRoom(roomData);
4889
+ return room;
4890
+ }
4891
+ async joinOrCreateRoom(options) {
4892
+ const response = await this.rpcClient.call(
4893
+ "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
4894
+ {
4895
+ options
4896
+ }
4897
+ );
4898
+ if (response.success === false) {
4899
+ throw new Error(response.error || "Failed to join or create room");
4900
+ }
4901
+ const data = response.value || response;
4902
+ const room = new exports.VenusRoom(data.roomData);
4903
+ return {
4904
+ action: data.action,
4905
+ room,
4906
+ playersJoined: data.playersJoined
4907
+ };
4908
+ }
4909
+ async joinRoomByCode(roomCode) {
4910
+ const response = await this.rpcClient.call(
4911
+ "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
4912
+ {
4913
+ roomCode
4914
+ }
4915
+ );
4916
+ if (response?.success === false) {
4917
+ throw new Error(response.error || "Failed to join room by code");
4918
+ }
4919
+ const roomData = response.roomData || response;
4920
+ const room = new exports.VenusRoom(roomData);
4921
+ return room;
4922
+ }
4923
+ // Get user's rooms with optional filtering
4924
+ async getUserRooms(includeArchived = false) {
4925
+ const response = await this.rpcClient.call(
4926
+ "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
4927
+ {
4928
+ includeArchived
4929
+ }
4930
+ );
4931
+ if (response?.success === false) {
4932
+ throw new Error(response.error || "Failed to get user rooms");
4933
+ }
4934
+ const rawRooms = response.rooms || [];
4935
+ const venusRooms = [];
4936
+ for (const roomData of rawRooms) {
4937
+ if (!roomData.id) {
4938
+ console.warn("getUserRooms: Skipping room with missing ID:", roomData);
4939
+ continue;
4940
+ }
4941
+ try {
4942
+ const venusRoom = new exports.VenusRoom(roomData);
4943
+ venusRooms.push(venusRoom);
4944
+ } catch (error) {
4945
+ console.warn(
4946
+ "getUserRooms: Failed to create VenusRoom object:",
4947
+ error,
4948
+ roomData
4949
+ );
4950
+ }
4951
+ }
4952
+ return venusRooms;
4953
+ }
4954
+ async updateData(room, updates, merge = true) {
4955
+ const response = await this.rpcClient.call(
4956
+ "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
4957
+ {
4958
+ roomId: room.id,
4959
+ updates,
4960
+ merge
4961
+ }
4962
+ );
4963
+ if (response?.success === false) {
4964
+ throw new Error(response.error || "Failed to update room data");
4965
+ }
4966
+ return response.data;
4967
+ }
4968
+ async getData(room) {
4969
+ const response = await this.rpcClient.call(
4970
+ "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
4971
+ {
4972
+ roomId: room.id
4973
+ }
4974
+ );
4975
+ if (response?.success === false) {
4976
+ throw new Error(response.error || "Failed to get room data");
4977
+ }
4978
+ return response.data;
4979
+ }
4980
+ async sendMessage(venusRoom, messageData) {
4981
+ const response = await this.rpcClient.call(
4982
+ "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
4983
+ {
4984
+ roomId: venusRoom.id,
4985
+ message: messageData
4986
+ }
4987
+ );
4988
+ if (response?.success === false) {
4989
+ throw new Error(response.error || "Failed to send message");
4990
+ }
4991
+ return response.messageId;
4992
+ }
4993
+ async leave(room) {
4994
+ const response = await this.rpcClient.call(
4995
+ "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
4996
+ {
4997
+ roomId: room.id
4998
+ }
4999
+ );
5000
+ if (response?.success === false) {
5001
+ throw new Error(response.error || "Failed to leave room");
5002
+ }
5003
+ return response;
5004
+ }
5005
+ async startGame(room, gameConfig = {}, turnOrder = null) {
5006
+ const response = await this.rpcClient.call(
5007
+ "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
5008
+ {
5009
+ roomId: room.id,
5010
+ gameConfig,
5011
+ turnOrder
5012
+ }
5013
+ );
5014
+ if (response?.success === false) {
5015
+ throw new Error(response.error || "Failed to start game");
5016
+ }
5017
+ return response.data;
5018
+ }
5019
+ async proposeMove(room, proposalPayload) {
5020
+ const response = await this.rpcClient.call(
5021
+ "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
5022
+ {
5023
+ roomId: room.id,
5024
+ gameSpecificState: proposalPayload.gameSpecificState,
5025
+ moveType: proposalPayload.moveType,
5026
+ clientContext: proposalPayload.clientContext,
5027
+ clientProposalId: proposalPayload.clientProposalId
5028
+ }
5029
+ );
5030
+ if (response?.success === false) {
5031
+ throw new Error(response.error || "Failed to propose move");
5032
+ }
5033
+ return response.data;
5034
+ }
5035
+ async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
5036
+ console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
5037
+ return { success: true, moveId, isValid, reason };
5038
+ }
5039
+ async roomSubscribeToGameEvents(room, callback) {
5040
+ "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5041
+ if (!this.subscriptions.gameEvents[room.id]) {
5042
+ this.subscriptions.gameEvents[room.id] = [];
5043
+ }
5044
+ this.subscriptions.gameEvents[room.id].push(callback);
5045
+ }
5046
+ subscribe(room, options = {}) {
5047
+ const subscriptionIds = [];
5048
+ const roomId = room.id;
5049
+ if (options.onData) {
5050
+ const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5051
+ if (!this.subscriptions.data[roomId]) {
5052
+ this.subscriptions.data[roomId] = [];
5053
+ }
5054
+ this.subscriptions.data[roomId].push(options.onData);
5055
+ subscriptionIds.push({
5056
+ type: "data",
5057
+ id: dataSubId,
5058
+ callback: options.onData
5059
+ });
5060
+ }
5061
+ if (options.onMessages) {
5062
+ const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5063
+ if (!this.subscriptions.messages[roomId]) {
5064
+ this.subscriptions.messages[roomId] = [];
5065
+ }
5066
+ this.subscriptions.messages[roomId].push(options.onMessages);
5067
+ subscriptionIds.push({
5068
+ type: "messages",
5069
+ id: msgSubId,
5070
+ callback: options.onMessages
5071
+ });
5072
+ }
5073
+ if (options.onMoves || options.onGameEvents) {
5074
+ const handler = options.onMoves || options.onGameEvents;
5075
+ if (handler) {
5076
+ const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5077
+ if (!this.subscriptions.gameEvents[roomId]) {
5078
+ this.subscriptions.gameEvents[roomId] = [];
5079
+ }
5080
+ this.subscriptions.gameEvents[roomId].push(handler);
5081
+ subscriptionIds.push({
5082
+ type: "gameEvents",
5083
+ id: gameSubId,
5084
+ callback: handler
5085
+ });
5086
+ }
5087
+ }
5088
+ 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;
5089
+ if (needsSubscription) {
5090
+ this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
5091
+ roomId,
5092
+ subscribeToData: !!options.onData,
5093
+ subscribeToMessages: !!options.onMessages,
5094
+ subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
5095
+ }).catch((error) => {
5096
+ console.error("Failed to set up room subscription:", error);
5097
+ });
5098
+ }
5099
+ let called = false;
5100
+ return () => {
5101
+ if (called) return;
5102
+ called = true;
5103
+ subscriptionIds.forEach((sub) => {
5104
+ const bucket = this.subscriptions[sub.type];
5105
+ const callbacks = bucket && bucket[roomId] || [];
5106
+ const index = callbacks.indexOf(sub.callback);
5107
+ if (index > -1) callbacks.splice(index, 1);
5108
+ });
5109
+ const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
5110
+ if (hasNoCallbacks) {
5111
+ this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
5112
+ roomId
5113
+ }).catch((error) => {
5114
+ console.error("Failed to clean up room subscription:", error);
5115
+ });
5116
+ }
5117
+ };
5118
+ }
5119
+ };
5120
+
4976
5121
  // src/social/RpcSocialApi.ts
4977
5122
  var RpcSocialApi = class {
4978
5123
  constructor(rpcClient) {
@@ -5019,9 +5164,9 @@ var RemoteHost = class {
5019
5164
  __publicField(this, "notifications");
5020
5165
  __publicField(this, "popups");
5021
5166
  __publicField(this, "profile");
5022
- __publicField(this, "system");
5023
5167
  __publicField(this, "cdn");
5024
5168
  __publicField(this, "time");
5169
+ __publicField(this, "post");
5025
5170
  __publicField(this, "ai");
5026
5171
  __publicField(this, "haptics");
5027
5172
  __publicField(this, "features");
@@ -5075,12 +5220,10 @@ var RemoteHost = class {
5075
5220
  this.navigation = new RpcNavigationApi(rpcClient, venusApi);
5076
5221
  this.notifications = new RpcNotificationsApi(rpcClient);
5077
5222
  this.popups = new RpcPopupsApi(rpcClient);
5078
- this.profile = new HostProfileApi(venusApi);
5079
- const deviceApi = new HostDeviceApi(venusApi);
5080
- const environmentApi = new HostEnvironmentApi(venusApi);
5081
- this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
5223
+ this.profile = new HostProfileApi();
5082
5224
  this.cdn = new HostCdnApi(getCdnBaseUrl());
5083
- this.time = new HostTimeApi(rpcClient, venusApi);
5225
+ this.time = new HostTimeApi(rpcClient);
5226
+ this.post = new RpcPostApi(rpcClient);
5084
5227
  this.ai = new RpcAiApi(rpcClient);
5085
5228
  this.haptics = new RpcHapticsApi(rpcClient);
5086
5229
  this.features = new RpcFeaturesApi(rpcClient);
@@ -5095,6 +5238,7 @@ var RemoteHost = class {
5095
5238
  venusApi.isMock = () => false;
5096
5239
  this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
5097
5240
  initializeRoomsApi(this.venusApi, this);
5241
+ console.log("[Venus SDK] Remote host created");
5098
5242
  }
5099
5243
  get isInitialized() {
5100
5244
  return this._isInitialized;
@@ -5113,27 +5257,35 @@ var RemoteHost = class {
5113
5257
  );
5114
5258
  transport.instanceId = response.instanceId;
5115
5259
  this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
5116
- const profile = response.profile;
5117
- const sanitizedProfile = {
5118
- id: profile.id,
5119
- username: profile.username,
5120
- avatarUrl: profile.avatarUrl ?? null,
5121
- isAnonymous: Boolean(profile.isAnonymous)
5122
- };
5123
- this.venusApi._profileData = sanitizedProfile;
5124
- this.venusApi._deviceData = response.device;
5125
- this.venusApi._environmentData = response.environment;
5126
- this.venusApi._localeData = response.locale;
5127
- this.venusApi._languageCodeData = response.languageCode;
5260
+ if (response.profile) {
5261
+ const profile = response.profile;
5262
+ const sanitizedProfile = {
5263
+ id: profile.id,
5264
+ username: profile.username,
5265
+ avatarUrl: profile.avatarUrl ?? null,
5266
+ isAnonymous: Boolean(profile.isAnonymous)
5267
+ };
5268
+ if (typeof window !== "undefined") {
5269
+ const globalWindow = window;
5270
+ const venus = globalWindow.venus || (globalWindow.venus = {});
5271
+ venus.profile = sanitizedProfile;
5272
+ if (venus._config) {
5273
+ venus._config.profile = sanitizedProfile;
5274
+ }
5275
+ if (venus.config) {
5276
+ venus.config.profile = sanitizedProfile;
5277
+ }
5278
+ }
5279
+ }
5128
5280
  this._isInitialized = true;
5129
- this.venusApi.launchParams = response.launchParams;
5281
+ this.venusApi.launchParams = response.launchParams || {};
5130
5282
  await this.rpcClient.call("READY" /* READY */, {});
5131
- const safeArea = response.safeArea;
5132
- if (safeArea) {
5133
- this.venusApi._safeAreaData = safeArea;
5283
+ const hudInsets = response.hudInsets;
5284
+ if (hudInsets) {
5285
+ this.venusApi.config.ui.safeArea = hudInsets;
5134
5286
  }
5135
5287
  return {
5136
- safeArea,
5288
+ hudInsets,
5137
5289
  initializeAsleep: response.initializeAsleep
5138
5290
  };
5139
5291
  }
@@ -5145,8 +5297,10 @@ var RemoteHost = class {
5145
5297
  // src/Host.ts
5146
5298
  function createHost(venusApi, isMock) {
5147
5299
  if (isMock) {
5300
+ console.log("[Venus SDK] Creating Local Host");
5148
5301
  return new MockHost(venusApi);
5149
5302
  } else {
5303
+ console.log("[Venus SDK] Creating Remote Host");
5150
5304
  return new RemoteHost(venusApi);
5151
5305
  }
5152
5306
  }
@@ -5159,35 +5313,15 @@ function initializeSocial(venusApi, host) {
5159
5313
  };
5160
5314
  }
5161
5315
 
5162
- // raw-loader:/Users/pchan/Development/series/venus/venus-sdk/packages/api/src/webview/webviewLibraryShim.js
5163
- var webviewLibraryShim_default = "/**\r\n * Venus Embedded Libraries WebView Shim\r\n *\r\n * This code is injected into H5 game WebViews BEFORE the game's main script runs.\r\n * It bootstraps the embedded libraries system by:\r\n * 1. Reading window.__venusLibrariesConfig (set by the Vite plugin)\r\n * 2. Loading libraries via RPC (mobile) or CDN (web)\r\n * 3. Registering libraries in window.__venusLibraryExports\r\n * 4. Allowing the game's virtual modules to access them\r\n *\r\n * This shim is NOT imported by H5 games - it's injected by the Venus host via\r\n * injectedJavaScriptBeforeContentLoaded in H5AppPoolRenderer.\r\n */\r\n\r\n;(function () {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {\r\n return\r\n }\r\n\r\n var RESPONSE_TYPE = 'H5_RESPONSE'\r\n var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET'\r\n var REQUEST_TIMEOUT_MS = 12000\r\n var pendingRequests = new Map()\r\n\r\n function ensureConfig() {\r\n if (!window.__venusLibrariesConfig) {\r\n window.__venusLibrariesConfig = {\r\n enabled: false,\r\n required: [],\r\n manifest: {},\r\n cdnBase: '',\r\n }\r\n }\r\n if (!window.__venusLibrariesConfig.manifest) {\r\n window.__venusLibrariesConfig.manifest = {}\r\n }\r\n if (!Array.isArray(window.__venusLibrariesConfig.required)) {\r\n window.__venusLibrariesConfig.required = []\r\n }\r\n return window.__venusLibrariesConfig\r\n }\r\n\r\n function ensureExportsRegistry() {\r\n if (!window.__venusLibraryExports) {\r\n window.__venusLibraryExports = {}\r\n }\r\n return window.__venusLibraryExports\r\n }\r\n\r\n function hasHostBridge() {\r\n return !!(\r\n window.ReactNativeWebView &&\r\n typeof window.ReactNativeWebView.postMessage === 'function'\r\n )\r\n }\r\n\r\n function registerResponseListeners() {\r\n if (\r\n window.__venusLibraryShim &&\r\n window.__venusLibraryShim.__listenerRegistered\r\n ) {\r\n return\r\n }\r\n\r\n function handleMessage(event) {\r\n var payload = parsePayload(event && event.data)\r\n if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {\r\n return\r\n }\r\n var requestId = payload.data.requestId\r\n if (!requestId || !pendingRequests.has(requestId)) {\r\n return\r\n }\r\n var pending = pendingRequests.get(requestId)\r\n pendingRequests.delete(requestId)\r\n clearTimeout(pending.timeout)\r\n\r\n if (payload.data.success === false) {\r\n pending.reject(\r\n new Error(payload.data.error || 'Embedded library load failed'),\r\n )\r\n return\r\n }\r\n\r\n var value = payload.data.value || payload.data\r\n if (!value || !value.base64Data) {\r\n pending.reject(\r\n new Error('Embedded library response was missing base64Data'),\r\n )\r\n return\r\n }\r\n\r\n pending.resolve(value.base64Data)\r\n }\r\n\r\n if (\r\n typeof document !== 'undefined' &&\r\n typeof document.addEventListener === 'function'\r\n ) {\r\n document.addEventListener('message', handleMessage, false)\r\n }\r\n if (\r\n typeof window !== 'undefined' &&\r\n typeof window.addEventListener === 'function'\r\n ) {\r\n window.addEventListener('message', handleMessage, false)\r\n }\r\n\r\n if (!window.__venusLibraryShim) {\r\n window.__venusLibraryShim = {}\r\n }\r\n window.__venusLibraryShim.__listenerRegistered = true\r\n }\r\n\r\n function parsePayload(raw) {\r\n if (!raw || typeof raw !== 'string') {\r\n return null\r\n }\r\n try {\r\n return JSON.parse(raw)\r\n } catch (error) {\r\n return null\r\n }\r\n }\r\n\r\n function createRequestId(libraryKey) {\r\n var sanitized = ''\r\n for (var i = 0; i < libraryKey.length; i++) {\r\n var c = libraryKey.charAt(i)\r\n if (\r\n (c >= 'a' && c <= 'z') ||\r\n (c >= 'A' && c <= 'Z') ||\r\n (c >= '0' && c <= '9') ||\r\n c === '-' ||\r\n c === '_'\r\n ) {\r\n sanitized += c\r\n } else {\r\n sanitized += '_'\r\n }\r\n }\r\n return (\r\n 'embedded-lib-' +\r\n sanitized +\r\n '-' +\r\n Date.now() +\r\n '-' +\r\n Math.random().toString(36).slice(2)\r\n )\r\n }\r\n\r\n function postHostRequest(assetKey, requestId) {\r\n if (!hasHostBridge()) {\r\n throw new Error('Host bridge is unavailable')\r\n }\r\n var bridge = window.ReactNativeWebView\r\n var message = {\r\n type: REQUEST_TYPE,\r\n direction: 'H5_TO_APP',\r\n data: {\r\n requestId: requestId,\r\n assetKey: assetKey,\r\n },\r\n instanceId:\r\n (window._venusInitState && window._venusInitState.poolId) || 'unknown',\r\n timestamp: Date.now(),\r\n }\r\n bridge.postMessage(JSON.stringify(message))\r\n }\r\n\r\n function loadLibraryViaHost(assetKey, libraryKey) {\r\n return new Promise(function (resolve, reject) {\r\n var requestId = createRequestId(libraryKey)\r\n var timeout = setTimeout(function () {\r\n pendingRequests.delete(requestId)\r\n reject(new Error('Timed out loading embedded library: ' + libraryKey))\r\n }, REQUEST_TIMEOUT_MS)\r\n\r\n pendingRequests.set(requestId, {\r\n resolve: resolve,\r\n reject: reject,\r\n timeout: timeout,\r\n })\r\n\r\n try {\r\n postHostRequest(assetKey, requestId)\r\n } catch (error) {\r\n pendingRequests.delete(requestId)\r\n clearTimeout(timeout)\r\n reject(error)\r\n }\r\n })\r\n }\r\n\r\n function buildCdnUrl(config, entry) {\r\n var base = config.cdnBase || ''\r\n if (!base.endsWith('/')) {\r\n base += '/'\r\n }\r\n var path = entry.cdnPath\r\n if (path.charAt(0) === '/') {\r\n path = path.substring(1)\r\n }\r\n return base + path\r\n }\r\n\r\n async function loadLibraryViaCdn(config, entry, libraryKey) {\r\n if (!config.cdnBase) {\r\n throw new Error('CDN base URL is not configured')\r\n }\r\n var url = buildCdnUrl(config, entry)\r\n var response = await fetch(url, { credentials: 'omit' })\r\n if (!response.ok) {\r\n throw new Error(\r\n 'Failed to fetch embedded library from CDN: ' + libraryKey,\r\n )\r\n }\r\n return await response.text()\r\n }\r\n\r\n function decodeBase64ToUtf8(base64) {\r\n if (typeof base64 !== 'string') {\r\n throw new Error('Invalid base64 payload')\r\n }\r\n\r\n if (typeof atob === 'function') {\r\n var binary = atob(base64)\r\n if (typeof TextDecoder !== 'undefined') {\r\n var len = binary.length\r\n var bytes = new Uint8Array(len)\r\n for (var i = 0; i < len; i++) {\r\n bytes[i] = binary.charCodeAt(i)\r\n }\r\n return new TextDecoder('utf-8').decode(bytes)\r\n }\r\n return decodeURIComponent(escape(binary))\r\n }\r\n\r\n var bufferCtor =\r\n (typeof globalThis !== 'undefined' && globalThis.Buffer) ||\r\n (typeof window !== 'undefined' && window.Buffer)\r\n if (bufferCtor) {\r\n return bufferCtor.from(base64, 'base64').toString('utf-8')\r\n }\r\n\r\n throw new Error('No base64 decoder available')\r\n }\r\n\r\n function evaluateLibrarySource(libraryKey, globalVar, source) {\r\n var registry = ensureExportsRegistry()\r\n if (!source) {\r\n throw new Error('Embedded library source was empty for ' + libraryKey)\r\n }\r\n\r\n var previousValue = window[globalVar]\r\n try {\r\n var executor = new Function(\r\n source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js',\r\n )\r\n executor.call(window)\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to evaluate embedded library ' +\r\n libraryKey +\r\n ': ' +\r\n (error && error.message ? error.message : error),\r\n )\r\n }\r\n\r\n var exported = window[globalVar] || previousValue\r\n if (!exported) {\r\n throw new Error(\r\n 'Embedded library ' + libraryKey + ' did not register ' + globalVar,\r\n )\r\n }\r\n\r\n registry[libraryKey] = exported\r\n return exported\r\n }\r\n\r\n async function ensureLibraryLoaded(config, libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n if (registry[libraryKey]) {\r\n return registry[libraryKey]\r\n }\r\n\r\n var entry = config.manifest && config.manifest[libraryKey]\r\n if (!entry) {\r\n throw new Error('No manifest entry for embedded library ' + libraryKey)\r\n }\r\n\r\n var source = null\r\n if (config.useHost !== false && hasHostBridge()) {\r\n try {\r\n var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey)\r\n source = decodeBase64ToUtf8(base64)\r\n } catch (error) {\r\n // Log the RPC error loudly before fallback\r\n console.error(\r\n '[Venus Libraries] Failed to load ' +\r\n libraryKey +\r\n ' from host via RPC:',\r\n error,\r\n )\r\n console.warn(\r\n '[Venus Libraries] Falling back to CDN for ' +\r\n libraryKey +\r\n '. This may indicate an asset packaging issue.',\r\n )\r\n }\r\n }\r\n\r\n if (!source) {\r\n source = await loadLibraryViaCdn(config, entry, libraryKey)\r\n }\r\n\r\n return evaluateLibrarySource(libraryKey, entry.globalVar, source)\r\n }\r\n\r\n async function bootstrap() {\r\n try {\r\n registerResponseListeners()\r\n getBootstrapPromise()\r\n\r\n var config = ensureConfig()\r\n\r\n if (!config.enabled) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n if (!Array.isArray(config.required) || config.required.length === 0) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n // Group libraries by load stage for parallel loading within stages\r\n var librariesByStage = {}\r\n for (var i = 0; i < config.required.length; i++) {\r\n var libraryKey = config.required[i]\r\n var entry = config.manifest[libraryKey]\r\n var stage = entry.loadStage || 0\r\n if (!librariesByStage[stage]) librariesByStage[stage] = []\r\n librariesByStage[stage].push(libraryKey)\r\n }\r\n\r\n // Load stages sequentially, libraries within each stage in parallel\r\n var stages = Object.keys(librariesByStage).sort(function (a, b) {\r\n return parseInt(a, 10) - parseInt(b, 10)\r\n })\r\n\r\n for (var s = 0; s < stages.length; s++) {\r\n var stage = stages[s]\r\n var libs = librariesByStage[stage]\r\n\r\n // Load all libraries in this stage in parallel\r\n var stagePromises = libs.map(function (libraryKey) {\r\n return ensureLibraryLoaded(config, libraryKey).catch(\r\n function (error) {\r\n console.error(\r\n '[Venus Libraries] Failed to load library ' + libraryKey,\r\n error,\r\n )\r\n throw error\r\n },\r\n )\r\n })\r\n\r\n await Promise.all(stagePromises)\r\n }\r\n\r\n if (bootstrapResolve) bootstrapResolve()\r\n } catch (error) {\r\n console.error('[Venus Libraries] Bootstrap error', error)\r\n if (bootstrapReject) bootstrapReject(error)\r\n throw error\r\n }\r\n }\r\n\r\n // Create a promise that resolves when bootstrap completes\r\n var bootstrapPromise = null\r\n var bootstrapResolve = null\r\n var bootstrapReject = null\r\n\r\n function getBootstrapPromise() {\r\n if (!bootstrapPromise) {\r\n bootstrapPromise = new Promise(function (resolve, reject) {\r\n bootstrapResolve = resolve\r\n bootstrapReject = reject\r\n })\r\n }\r\n return bootstrapPromise\r\n }\r\n\r\n window.__venusLibraryShim = {\r\n bootstrap: bootstrap,\r\n ready: getBootstrapPromise,\r\n getExports: function (libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n return registry[libraryKey]\r\n },\r\n __initialized: true,\r\n }\r\n})()\r\n";
5164
-
5165
- // src/webview/webviewLibraryShimSource.ts
5166
- var WEBVIEW_LIBRARY_SHIM_SOURCE = webviewLibraryShim_default;
5167
- function getWebviewLibraryShimSource() {
5168
- return WEBVIEW_LIBRARY_SHIM_SOURCE;
5169
- }
5170
-
5171
- exports.DEFAULT_SHARED_LIB_CDN_BASE = DEFAULT_SHARED_LIB_CDN_BASE;
5172
- exports.EMBEDDED_LIBRARIES = EMBEDDED_LIBRARIES;
5173
- exports.EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARY_BY_KEY;
5174
- exports.HASH_ALGORITHM_NODE = HASH_ALGORITHM_NODE;
5175
- exports.HASH_ALGORITHM_WEB_CRYPTO = HASH_ALGORITHM_WEB_CRYPTO;
5176
5316
  exports.HapticFeedbackStyle = HapticFeedbackStyle;
5177
5317
  exports.HostCdnApi = HostCdnApi;
5178
- exports.HostDeviceApi = HostDeviceApi;
5179
- exports.HostEnvironmentApi = HostEnvironmentApi;
5180
5318
  exports.HostProfileApi = HostProfileApi;
5181
- exports.HostSystemApi = HostSystemApi;
5182
5319
  exports.HostTimeApi = HostTimeApi;
5183
- exports.MODULE_TO_LIBRARY_SPECIFIERS = MODULE_TO_LIBRARY_SPECIFIERS;
5184
5320
  exports.MockAdsApi = MockAdsApi;
5185
5321
  exports.MockAiApi = MockAiApi;
5186
5322
  exports.MockAnalyticsApi = MockAnalyticsApi;
5187
5323
  exports.MockAvatarApi = MockAvatarApi;
5188
5324
  exports.MockCdnApi = MockCdnApi;
5189
- exports.MockDeviceApi = MockDeviceApi;
5190
- exports.MockEnvironmentApi = MockEnvironmentApi;
5191
5325
  exports.MockFeaturesApi = MockFeaturesApi;
5192
5326
  exports.MockHapticsApi = MockHapticsApi;
5193
5327
  exports.MockIapApi = MockIapApi;
@@ -5200,9 +5334,9 @@ exports.MockPopupsApi = MockPopupsApi;
5200
5334
  exports.MockPreloaderApi = MockPreloaderApi;
5201
5335
  exports.MockProfileApi = MockProfileApi;
5202
5336
  exports.MockSharedAssetsApi = MockSharedAssetsApi;
5337
+ exports.MockSimulationApi = MockSimulationApi;
5203
5338
  exports.MockSocialApi = MockSocialApi;
5204
5339
  exports.MockStorageApi = MockStorageApi;
5205
- exports.MockSystemApi = MockSystemApi;
5206
5340
  exports.MockTimeApi = MockTimeApi;
5207
5341
  exports.RemoteHost = RemoteHost;
5208
5342
  exports.RpcAdsApi = RpcAdsApi;
@@ -5220,22 +5354,14 @@ exports.RpcNavigationApi = RpcNavigationApi;
5220
5354
  exports.RpcNotificationsApi = RpcNotificationsApi;
5221
5355
  exports.RpcPopupsApi = RpcPopupsApi;
5222
5356
  exports.RpcPreloaderApi = RpcPreloaderApi;
5223
- exports.RpcRoomsApi = RpcRoomsApi;
5224
5357
  exports.RpcSharedAssetsApi = RpcSharedAssetsApi;
5225
5358
  exports.RpcSimulationApi = RpcSimulationApi;
5226
5359
  exports.RpcSocialApi = RpcSocialApi;
5227
5360
  exports.RpcStorageApi = RpcStorageApi;
5228
5361
  exports.SDK_VERSION = SDK_VERSION;
5229
5362
  exports.VenusMessageId = VenusMessageId;
5230
- exports.VenusRoom = VenusRoom;
5231
- exports.WEBVIEW_LIBRARY_SHIM_SOURCE = WEBVIEW_LIBRARY_SHIM_SOURCE;
5232
- exports.base64ToArrayBuffer = base64ToArrayBuffer;
5233
- exports.base64ToUtf8 = base64ToUtf8;
5234
- exports.computeScoreHash = computeScoreHash;
5235
5363
  exports.createHost = createHost;
5236
5364
  exports.createMockStorageApi = createMockStorageApi;
5237
- exports.getLibraryDefinition = getLibraryDefinition;
5238
- exports.getWebviewLibraryShimSource = getWebviewLibraryShimSource;
5239
5365
  exports.initializeAds = initializeAds;
5240
5366
  exports.initializeAi = initializeAi;
5241
5367
  exports.initializeAnalytics = initializeAnalytics;
@@ -5256,7 +5382,6 @@ exports.initializeSimulation = initializeSimulation;
5256
5382
  exports.initializeSocial = initializeSocial;
5257
5383
  exports.initializeStackNavigation = initializeStackNavigation;
5258
5384
  exports.initializeStorage = initializeStorage;
5259
- exports.initializeSystem = initializeSystem;
5260
5385
  exports.initializeTime = initializeTime;
5261
5386
  exports.isPacificDaylightTime = isPacificDaylightTime;
5262
5387
  exports.setupRoomNotifications = setupRoomNotifications;