@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
@@ -1,5 +1,219 @@
1
- import { createMockDelay, MOCK_DELAYS, isWebPlatform } from './chunk-QABXMFND.mjs';
2
- import { __publicField } from './chunk-NSSMTXJJ.mjs';
1
+ import { __esm, __export, __publicField, createMockDelay, MOCK_DELAYS, isWebPlatform, __toCommonJS } from './chunk-W7IPHM67.mjs';
2
+
3
+ // src/rooms/VenusRoom.ts
4
+ var VenusRoom;
5
+ var init_VenusRoom = __esm({
6
+ "src/rooms/VenusRoom.ts"() {
7
+ VenusRoom = class {
8
+ constructor(roomData) {
9
+ __publicField(this, "id");
10
+ __publicField(this, "name");
11
+ __publicField(this, "players");
12
+ __publicField(this, "maxPlayers");
13
+ __publicField(this, "gameType");
14
+ __publicField(this, "appId");
15
+ __publicField(this, "type");
16
+ __publicField(this, "createdBy");
17
+ __publicField(this, "createdAt");
18
+ __publicField(this, "updatedAt");
19
+ __publicField(this, "isPrivate");
20
+ __publicField(this, "currentPlayers");
21
+ __publicField(this, "status");
22
+ __publicField(this, "customMetadata");
23
+ __publicField(this, "admins");
24
+ __publicField(this, "roomCode");
25
+ __publicField(this, "description");
26
+ __publicField(this, "data");
27
+ __publicField(this, "version");
28
+ __publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
29
+ this.id = roomData.id;
30
+ this.name = roomData.name;
31
+ this.players = roomData.currentPlayers || [];
32
+ this.maxPlayers = roomData.maxPlayers;
33
+ this.gameType = roomData.gameType;
34
+ this.appId = roomData.appId;
35
+ this.type = roomData.type;
36
+ this.createdBy = roomData.createdBy;
37
+ this.createdAt = roomData.createdAt;
38
+ this.updatedAt = roomData.updatedAt;
39
+ this.isPrivate = roomData.isPrivate;
40
+ this.currentPlayers = roomData.currentPlayers || [];
41
+ this.status = roomData.status;
42
+ this.customMetadata = roomData.customMetadata || {};
43
+ this.admins = roomData.admins || [];
44
+ this.roomCode = roomData.roomCode;
45
+ this.description = roomData.description;
46
+ this.data = roomData.data || {};
47
+ this.version = roomData.version;
48
+ console.log(`VenusRoom: Created room object for ${this.id}`, {
49
+ hasCustomMetadata: !!this.customMetadata,
50
+ hasGameState: !!this.customMetadata?.rules?.gameState,
51
+ gamePhase: this.customMetadata?.rules?.gameState?.phase,
52
+ currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
53
+ });
54
+ }
55
+ updateFromRoomData(newRoomData) {
56
+ if (newRoomData.id === this.id) {
57
+ this.name = newRoomData.name || this.name;
58
+ this.players = newRoomData.currentPlayers || this.players;
59
+ this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
60
+ this.gameType = newRoomData.gameType || this.gameType;
61
+ this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
62
+ this.customMetadata = newRoomData.customMetadata || this.customMetadata;
63
+ this.data = newRoomData.data || this.data;
64
+ this.status = newRoomData.status || this.status;
65
+ this.updatedAt = newRoomData.updatedAt || this.updatedAt;
66
+ console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
67
+ hasCustomMetadata: !!this.customMetadata,
68
+ hasGameState: !!this.customMetadata?.rules?.gameState,
69
+ gamePhase: this.customMetadata?.rules?.gameState?.phase,
70
+ currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
71
+ });
72
+ }
73
+ }
74
+ };
75
+ }
76
+ });
77
+
78
+ // src/rooms/RoomsApi.ts
79
+ var init_RoomsApi = __esm({
80
+ "src/rooms/RoomsApi.ts"() {
81
+ }
82
+ });
83
+
84
+ // src/rooms/index.ts
85
+ var rooms_exports = {};
86
+ __export(rooms_exports, {
87
+ VenusRoom: () => VenusRoom,
88
+ initializeRoomsApi: () => initializeRoomsApi,
89
+ setupRoomNotifications: () => setupRoomNotifications
90
+ });
91
+ function bindMethod(target, targetKey, source, sourceKey) {
92
+ const key = sourceKey ?? targetKey;
93
+ const fn = source?.[key];
94
+ if (typeof fn === "function") {
95
+ target[targetKey] = fn.bind(source);
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+ function setupRoomNotifications(transport, getSubscriptions) {
101
+ console.log("[Venus Rooms] Setting up room notification listeners");
102
+ return transport.onVenusMessage((message) => {
103
+ const subscriptions = getSubscriptions();
104
+ if (!subscriptions) {
105
+ return;
106
+ }
107
+ if (message.type === "H5_ROOM_DATA_UPDATED") {
108
+ const messageData = message.data;
109
+ const { roomId, roomData } = messageData;
110
+ if (!roomId) return;
111
+ const callbacks = subscriptions.data?.[roomId] || [];
112
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
113
+ console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
114
+ callbacks.forEach((callback) => {
115
+ try {
116
+ callback(roomData);
117
+ } catch (error) {
118
+ console.error("[Venus Rooms] Error in room data callback:", error);
119
+ throw error;
120
+ }
121
+ });
122
+ allEventsCallbacks.forEach((callback) => {
123
+ try {
124
+ callback({ type: message.type, ...messageData });
125
+ } catch (error) {
126
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
127
+ throw error;
128
+ }
129
+ });
130
+ }
131
+ if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
132
+ const messageData = message.data;
133
+ const { roomId } = messageData;
134
+ if (!roomId) return;
135
+ const callbacks = subscriptions.messages?.[roomId] || [];
136
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
137
+ console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
138
+ callbacks.forEach((callback) => {
139
+ try {
140
+ callback(messageData);
141
+ } catch (error) {
142
+ console.error("[Venus Rooms] Error in room message callback:", error);
143
+ throw error;
144
+ }
145
+ });
146
+ allEventsCallbacks.forEach((callback) => {
147
+ try {
148
+ callback({ type: message.type, ...messageData });
149
+ } catch (error) {
150
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
151
+ throw error;
152
+ }
153
+ });
154
+ }
155
+ if (message.type === "app:h5:proposedMoveValidationUpdated") {
156
+ const messageData = message.data;
157
+ const { roomId } = messageData;
158
+ if (!roomId) return;
159
+ const callbacks = subscriptions.gameEvents?.[roomId] || [];
160
+ const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
161
+ console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
162
+ callbacks.forEach((callback) => {
163
+ try {
164
+ callback(messageData);
165
+ } catch (error) {
166
+ console.error("[Venus Rooms] Error in game event callback:", error);
167
+ throw error;
168
+ }
169
+ });
170
+ allEventsCallbacks.forEach((callback) => {
171
+ try {
172
+ callback({ type: message.type, ...messageData });
173
+ } catch (error) {
174
+ console.error("[Venus Rooms] Error in allEvents callback:", error);
175
+ throw error;
176
+ }
177
+ });
178
+ }
179
+ });
180
+ }
181
+ function initializeRoomsApi(venusApi, host) {
182
+ const roomsApi = host?.rooms;
183
+ if (!roomsApi) {
184
+ console.warn(
185
+ "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
186
+ );
187
+ return;
188
+ }
189
+ const venus = venusApi;
190
+ const existingNamespace = venus.rooms || {};
191
+ const roomsNamespace = Object.assign({}, existingNamespace);
192
+ const namespaceBindings = [
193
+ ["create", "createRoom"],
194
+ ["joinOrCreate", "joinOrCreateRoom"],
195
+ ["joinByCode", "joinRoomByCode"],
196
+ ["list", "getUserRooms"],
197
+ ["subscribeToRoom", "subscribe"],
198
+ ["updateRoomData", "updateData"],
199
+ ["getRoomData", "getData"],
200
+ ["sendRoomMessage", "sendMessage"],
201
+ ["leaveRoom", "leave"],
202
+ ["startRoomGame", "startGame"],
203
+ ["proposeMove"],
204
+ ["validateMove"]
205
+ ];
206
+ namespaceBindings.forEach(([targetKey, sourceKey]) => {
207
+ bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
208
+ });
209
+ venus.rooms = roomsNamespace;
210
+ }
211
+ var init_rooms = __esm({
212
+ "src/rooms/index.ts"() {
213
+ init_RoomsApi();
214
+ init_VenusRoom();
215
+ }
216
+ });
3
217
 
4
218
  // src/VenusMessageId.ts
5
219
  var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
@@ -47,6 +261,10 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
47
261
  VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
48
262
  VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
49
263
  VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
264
+ VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
265
+ VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
266
+ VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
267
+ VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
50
268
  VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
51
269
  VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
52
270
  VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
@@ -88,14 +306,11 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
88
306
  VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
89
307
  VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
90
308
  VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
91
- VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
92
- VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
93
- VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
94
- VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
309
+ VenusMessageId2["H5_LEADERBOARD_START_RUN"] = "H5_LEADERBOARD_START_RUN";
95
310
  VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
96
- VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
97
- VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
98
- VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
311
+ VenusMessageId2["H5_LEADERBOARD_GET"] = "H5_LEADERBOARD_GET";
312
+ VenusMessageId2["H5_LEADERBOARD_GET_HIGHLIGHT"] = "H5_LEADERBOARD_GET_HIGHLIGHT";
313
+ VenusMessageId2["H5_LEADERBOARD_GET_PLAYER_STATS"] = "H5_LEADERBOARD_GET_PLAYER_STATS";
99
314
  VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
100
315
  VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
101
316
  VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
@@ -338,7 +553,7 @@ var MockAvatarApi = class {
338
553
  async deleteAvatar() {
339
554
  console.log(`[Venus Mock] Deleting avatar3d config`);
340
555
  const venusApi = this._venusApi;
341
- const currentProfile = venusApi.getProfile();
556
+ const currentProfile = venusApi.getCurrentProfile();
342
557
  const profileId = currentProfile?.id || "default_profile";
343
558
  localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
344
559
  console.log(
@@ -353,7 +568,7 @@ var MockAvatarApi = class {
353
568
  console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
354
569
  config = await this.selectAvatarConfig(avatar3dId, false);
355
570
  } else {
356
- const currentProfile = venusApi.getProfile();
571
+ const currentProfile = venusApi.getCurrentProfile();
357
572
  const profileId = currentProfile?.id || "default_profile";
358
573
  console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
359
574
  console.log(
@@ -370,7 +585,7 @@ var MockAvatarApi = class {
370
585
  async saveAvatar(config) {
371
586
  console.log(`[Venus Mock] Saving avatar3d config:`, config);
372
587
  const venusApi = this._venusApi;
373
- const currentProfile = venusApi.getProfile();
588
+ const currentProfile = venusApi.getCurrentProfile();
374
589
  const profileId = currentProfile?.id || "default_profile";
375
590
  localStorage.setItem(
376
591
  `venus-mock-avatar3d-${profileId}`,
@@ -901,15 +1116,9 @@ var HostCdnApi = class {
901
1116
 
902
1117
  // src/cdn/MockCdnApi.ts
903
1118
  var MockCdnApi = class {
904
- constructor(venusApi) {
905
- __publicField(this, "venusApi");
906
- this.venusApi = venusApi;
907
- }
908
- get baseUrl() {
909
- return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
910
- }
911
- get forceRemoteCdn() {
912
- return this.venusApi._mock?.cdnForceRemote ?? false;
1119
+ constructor() {
1120
+ __publicField(this, "baseUrl");
1121
+ this.baseUrl = "https://venus-static-01293ak.web.app/";
913
1122
  }
914
1123
  async fetchBlob(path, options) {
915
1124
  const controller = new AbortController();
@@ -946,10 +1155,6 @@ var MockCdnApi = class {
946
1155
  return subPath;
947
1156
  }
948
1157
  const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
949
- const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
950
- if (isLocalhost && !this.forceRemoteCdn) {
951
- return `/${cleanSubPath}`;
952
- }
953
1158
  const pathParts = cleanSubPath.split("/");
954
1159
  const encodedParts = pathParts.map((part, index) => {
955
1160
  return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
@@ -1071,212 +1276,6 @@ function initializeCdn(venusApi, host) {
1071
1276
  venusApi.cdn = host.cdn;
1072
1277
  }
1073
1278
 
1074
- // src/device/HostDeviceApi.ts
1075
- var HostDeviceApi = class {
1076
- constructor(venusApi) {
1077
- __publicField(this, "venusApi");
1078
- this.venusApi = venusApi;
1079
- }
1080
- getDevice() {
1081
- const device = this.venusApi._deviceData;
1082
- if (!device) {
1083
- throw new Error(
1084
- "[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
1085
- );
1086
- }
1087
- return device;
1088
- }
1089
- };
1090
-
1091
- // src/device/MockDeviceApi.ts
1092
- var MockDeviceApi = class {
1093
- constructor(venusApi) {
1094
- __publicField(this, "venusApi");
1095
- this.venusApi = venusApi;
1096
- }
1097
- getDevice() {
1098
- const width = typeof window !== "undefined" ? window.innerWidth : 400;
1099
- const height = typeof window !== "undefined" ? window.innerHeight : 800;
1100
- return {
1101
- screenSize: { width, height },
1102
- viewportSize: {
1103
- width: width - 20,
1104
- // account for safe area
1105
- height: height - 20
1106
- },
1107
- orientation: width > height ? "landscape" : "portrait",
1108
- pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
1109
- fontScale: 1,
1110
- deviceType: width > 768 ? "tablet" : "phone",
1111
- hapticsEnabled: false,
1112
- haptics: { supported: false, enabled: false }
1113
- };
1114
- }
1115
- };
1116
-
1117
- // src/environment/HostEnvironmentApi.ts
1118
- var HostEnvironmentApi = class {
1119
- constructor(venusApi) {
1120
- __publicField(this, "venusApi");
1121
- this.venusApi = venusApi;
1122
- }
1123
- getEnvironment() {
1124
- const environment = this.venusApi._environmentData;
1125
- if (!environment) {
1126
- throw new Error(
1127
- "[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
1128
- );
1129
- }
1130
- return environment;
1131
- }
1132
- };
1133
-
1134
- // src/environment/MockEnvironmentApi.ts
1135
- var MockEnvironmentApi = class {
1136
- constructor(venusApi) {
1137
- __publicField(this, "venusApi");
1138
- this.venusApi = venusApi;
1139
- }
1140
- getEnvironment() {
1141
- const getBrowser = () => {
1142
- if (typeof navigator === "undefined") return "unknown";
1143
- const userAgent = navigator.userAgent;
1144
- if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
1145
- if (/firefox|fxios/i.test(userAgent)) return "firefox";
1146
- if (/safari/i.test(userAgent)) return "safari";
1147
- if (/edg/i.test(userAgent)) return "edge";
1148
- if (/opera|opr/i.test(userAgent)) return "opera";
1149
- return "unknown";
1150
- };
1151
- return {
1152
- isDevelopment: true,
1153
- platform: "web",
1154
- platformVersion: "mock-1.0",
1155
- browserInfo: {
1156
- browser: getBrowser(),
1157
- userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
1158
- isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
1159
- isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
1160
- language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
1161
- }
1162
- };
1163
- }
1164
- };
1165
-
1166
- // src/system/HostSystemApi.ts
1167
- var HostSystemApi = class {
1168
- constructor(deviceApi, environmentApi, venusApi) {
1169
- __publicField(this, "deviceApi");
1170
- __publicField(this, "environmentApi");
1171
- __publicField(this, "venusApi");
1172
- this.deviceApi = deviceApi;
1173
- this.environmentApi = environmentApi;
1174
- this.venusApi = venusApi;
1175
- }
1176
- getDevice() {
1177
- return this.deviceApi.getDevice();
1178
- }
1179
- getEnvironment() {
1180
- return this.environmentApi.getEnvironment();
1181
- }
1182
- getSafeArea() {
1183
- const safeArea = this.venusApi._safeAreaData;
1184
- if (!safeArea) {
1185
- throw new Error(
1186
- "[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
1187
- );
1188
- }
1189
- return { ...safeArea };
1190
- }
1191
- isMobile() {
1192
- const environment = this.environmentApi.getEnvironment();
1193
- if (environment.platform === "ios" || environment.platform === "android") {
1194
- return true;
1195
- }
1196
- if (environment.browserInfo) {
1197
- return environment.browserInfo.isMobile;
1198
- }
1199
- return true;
1200
- }
1201
- isWeb() {
1202
- const environment = this.environmentApi.getEnvironment();
1203
- if (environment.platform === "web") {
1204
- return true;
1205
- }
1206
- if (environment.browserInfo && !environment.browserInfo.isMobile) {
1207
- return true;
1208
- }
1209
- return false;
1210
- }
1211
- };
1212
-
1213
- // src/system/MockSystemApi.ts
1214
- var MockSystemApi = class {
1215
- constructor(deviceApi, environmentApi, venusApi) {
1216
- __publicField(this, "deviceApi");
1217
- __publicField(this, "environmentApi");
1218
- __publicField(this, "venusApi");
1219
- this.deviceApi = deviceApi;
1220
- this.environmentApi = environmentApi;
1221
- this.venusApi = venusApi;
1222
- }
1223
- getDevice() {
1224
- return this.deviceApi.getDevice();
1225
- }
1226
- getEnvironment() {
1227
- return this.environmentApi.getEnvironment();
1228
- }
1229
- getSafeArea() {
1230
- const safeArea = this.venusApi._safeAreaData;
1231
- if (!safeArea) {
1232
- return {
1233
- top: 0,
1234
- right: 0,
1235
- bottom: 34,
1236
- left: 0
1237
- };
1238
- }
1239
- return { ...safeArea };
1240
- }
1241
- isMobile() {
1242
- const environment = this.environmentApi.getEnvironment();
1243
- if (environment.platform === "ios" || environment.platform === "android") {
1244
- return true;
1245
- }
1246
- if (environment.browserInfo) {
1247
- return environment.browserInfo.isMobile;
1248
- }
1249
- return true;
1250
- }
1251
- isWeb() {
1252
- const environment = this.environmentApi.getEnvironment();
1253
- if (environment.platform === "web") {
1254
- return true;
1255
- }
1256
- if (environment.browserInfo && !environment.browserInfo.isMobile) {
1257
- return true;
1258
- }
1259
- return false;
1260
- }
1261
- };
1262
-
1263
- // src/system/index.ts
1264
- function initializeSystem(venusApi, host) {
1265
- venusApi.system = host.system;
1266
- venusApi.isMobile = () => {
1267
- console.warn(
1268
- "[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
1269
- );
1270
- return host.system.isMobile();
1271
- };
1272
- venusApi.isWeb = () => {
1273
- console.warn(
1274
- "[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
1275
- );
1276
- return host.system.isWeb();
1277
- };
1278
- }
1279
-
1280
1279
  // src/features/RpcFeaturesApi.ts
1281
1280
  var RpcFeaturesApi = class {
1282
1281
  constructor(rcpClient) {
@@ -1759,8 +1758,13 @@ var MockNotificationsApi = class {
1759
1758
  async cancelNotification(notificationId) {
1760
1759
  const venusApi = this.venusApi;
1761
1760
  if (isWebPlatform()) {
1761
+ console.log(
1762
+ "[Venus Mock] Cancel notification on web platform (simulated):",
1763
+ notificationId
1764
+ );
1762
1765
  return true;
1763
1766
  }
1767
+ console.log("[Venus Mock] Cancel local notification:", notificationId);
1764
1768
  await createMockDelay(MOCK_DELAYS.short);
1765
1769
  if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
1766
1770
  delete venusApi._mock.scheduledNotifications[notificationId];
@@ -1770,8 +1774,12 @@ var MockNotificationsApi = class {
1770
1774
  }
1771
1775
  async getAllScheduledLocalNotifications() {
1772
1776
  if (isWebPlatform()) {
1777
+ console.log(
1778
+ "[Venus Mock] Get notifications on web platform (returning empty list)"
1779
+ );
1773
1780
  return [];
1774
1781
  }
1782
+ console.log("[Venus Mock] Get all scheduled local notifications");
1775
1783
  await createMockDelay(MOCK_DELAYS.short);
1776
1784
  const venusApi = this.venusApi;
1777
1785
  const notifications = venusApi._mock.scheduledNotifications || {};
@@ -1779,8 +1787,10 @@ var MockNotificationsApi = class {
1779
1787
  }
1780
1788
  async isLocalNotificationsEnabled() {
1781
1789
  if (isWebPlatform()) {
1790
+ console.log("[Venus Mock] Notifications not available on web platform");
1782
1791
  return false;
1783
1792
  }
1793
+ console.log("[Venus Mock] Check if local notifications are enabled");
1784
1794
  await createMockDelay(MOCK_DELAYS.short);
1785
1795
  const venusApi = this.venusApi;
1786
1796
  const isEnabled = venusApi._mock.notificationsEnabled !== false;
@@ -1789,6 +1799,9 @@ var MockNotificationsApi = class {
1789
1799
  async scheduleAsync(title, body, seconds, notificationId, options) {
1790
1800
  const { priority = 50, groupId, payload } = options || {};
1791
1801
  if (isWebPlatform()) {
1802
+ console.log(
1803
+ "[Venus Mock] Notifications not supported on web platform, simulating success"
1804
+ );
1792
1805
  console.info(
1793
1806
  "\u{1F514} [Venus Mock] Notification would be scheduled:",
1794
1807
  title || "Untitled",
@@ -1799,11 +1812,14 @@ var MockNotificationsApi = class {
1799
1812
  const mockId = `mock-web-notification-${Date.now()}`;
1800
1813
  return mockId;
1801
1814
  }
1815
+ console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
1802
1816
  const venusApi = this.venusApi;
1803
1817
  if (!venusApi._mock.pendingRequests) {
1818
+ console.log("[Venus Mock] Initializing pendingRequests");
1804
1819
  venusApi._mock.pendingRequests = {};
1805
1820
  }
1806
1821
  const requestId = Date.now().toString();
1822
+ console.log("[Venus Mock] Creating request with ID:", requestId);
1807
1823
  return new Promise((resolve) => {
1808
1824
  venusApi._mock.pendingRequests[requestId] = { resolve };
1809
1825
  const id = notificationId || `mock-notification-${Date.now()}`;
@@ -1825,8 +1841,13 @@ var MockNotificationsApi = class {
1825
1841
  async setLocalNotificationsEnabled(enabled) {
1826
1842
  const venusApi = this.venusApi;
1827
1843
  if (isWebPlatform()) {
1844
+ console.log(
1845
+ "[Venus Mock] Set notifications enabled on web platform (simulated):",
1846
+ enabled
1847
+ );
1828
1848
  return true;
1829
1849
  }
1850
+ console.log("[Venus Mock] Set local notifications enabled:", enabled);
1830
1851
  await createMockDelay(MOCK_DELAYS.short);
1831
1852
  venusApi._mock.notificationsEnabled = enabled;
1832
1853
  return enabled;
@@ -2051,20 +2072,16 @@ function initializePopups(venusApi, host) {
2051
2072
 
2052
2073
  // src/profile/HostProfileApi.ts
2053
2074
  var HostProfileApi = class {
2054
- constructor(venusApi) {
2055
- __publicField(this, "venusApi");
2056
- this.venusApi = venusApi;
2057
- }
2058
2075
  getCurrentProfile() {
2059
- const profile = this.venusApi._profileData;
2076
+ const profile = window.venus?.profile;
2060
2077
  if (!profile) {
2061
2078
  throw new Error(
2062
- "[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
2079
+ "[Venus SDK] Host profile handshake did not complete. Await VenusAPI.initializeAsync() so INIT_SDK can deliver the profile before calling profile APIs."
2063
2080
  );
2064
2081
  }
2065
2082
  if (!profile.id || !profile.username) {
2066
2083
  throw new Error(
2067
- "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
2084
+ "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply real credentials before rooms APIs are used."
2068
2085
  );
2069
2086
  }
2070
2087
  return {
@@ -2078,10 +2095,6 @@ var HostProfileApi = class {
2078
2095
 
2079
2096
  // src/profile/MockProfileApi.ts
2080
2097
  var MockProfileApi = class {
2081
- constructor(venusApi) {
2082
- __publicField(this, "venusApi");
2083
- this.venusApi = venusApi;
2084
- }
2085
2098
  getCurrentProfile() {
2086
2099
  return {
2087
2100
  id: "mock_profile_123",
@@ -2094,22 +2107,11 @@ var MockProfileApi = class {
2094
2107
 
2095
2108
  // src/profile/index.ts
2096
2109
  function initializeProfile(venusApi, host) {
2097
- venusApi.getProfile = () => {
2098
- return host.profile.getCurrentProfile();
2099
- };
2100
2110
  venusApi.getCurrentProfile = () => {
2101
- console.warn(
2102
- "[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
2103
- );
2104
2111
  return host.profile.getCurrentProfile();
2105
2112
  };
2106
2113
  }
2107
2114
 
2108
- // src/utils/idGenerator.ts
2109
- function generateId() {
2110
- return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2111
- }
2112
-
2113
2115
  // src/rpc/RpcClient.ts
2114
2116
  var RpcClient = class {
2115
2117
  constructor() {
@@ -2152,7 +2154,7 @@ var RpcClient = class {
2152
2154
  }
2153
2155
  async call(method, args, timeout = 5e3) {
2154
2156
  return new Promise((resolve, reject) => {
2155
- const id = generateId();
2157
+ const id = this.generateId();
2156
2158
  this.addPendingCall(id, resolve, reject);
2157
2159
  const request = {
2158
2160
  type: "rpc-request",
@@ -2189,6 +2191,9 @@ var RpcClient = class {
2189
2191
  getPendingCall(id) {
2190
2192
  return this.pendingCalls.get(id);
2191
2193
  }
2194
+ generateId() {
2195
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2196
+ }
2192
2197
  handleRpcResponse(response) {
2193
2198
  const pending = this.getPendingCall(response.id);
2194
2199
  if (!pending) {
@@ -2210,449 +2215,29 @@ var RpcClient = class {
2210
2215
  }
2211
2216
  };
2212
2217
 
2213
- // src/rooms/VenusRoom.ts
2214
- var VenusRoom = class {
2215
- constructor(roomData) {
2216
- __publicField(this, "id");
2217
- __publicField(this, "name");
2218
- __publicField(this, "players");
2219
- __publicField(this, "maxPlayers");
2220
- __publicField(this, "gameType");
2221
- __publicField(this, "appId");
2222
- __publicField(this, "type");
2223
- __publicField(this, "createdBy");
2224
- __publicField(this, "createdAt");
2225
- __publicField(this, "updatedAt");
2226
- __publicField(this, "isPrivate");
2227
- __publicField(this, "status");
2228
- __publicField(this, "customMetadata");
2229
- __publicField(this, "admins");
2230
- __publicField(this, "roomCode");
2231
- __publicField(this, "description");
2232
- __publicField(this, "data");
2233
- __publicField(this, "version");
2234
- this.id = roomData.id;
2235
- this.name = roomData.name;
2236
- this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
2237
- this.maxPlayers = roomData.maxPlayers;
2238
- this.gameType = roomData.gameType;
2239
- this.appId = roomData.appId;
2240
- this.type = roomData.type;
2241
- this.createdBy = roomData.createdBy;
2242
- this.createdAt = roomData.createdAt;
2243
- this.updatedAt = roomData.updatedAt;
2244
- this.isPrivate = roomData.isPrivate;
2245
- this.status = roomData.status;
2246
- this.customMetadata = roomData.customMetadata || {};
2247
- this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
2248
- this.roomCode = roomData.roomCode;
2249
- this.description = roomData.description;
2250
- this.data = roomData.data || {};
2251
- this.version = roomData.version;
2218
+ // src/storage/MockStorageApi.ts
2219
+ function createMockStorageApi(storageType, appUrl) {
2220
+ const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2221
+ let prefix;
2222
+ let syncDelay = 0;
2223
+ switch (storageType) {
2224
+ case "deviceCache":
2225
+ prefix = "venus:app";
2226
+ syncDelay = 0;
2227
+ break;
2228
+ case "appStorage":
2229
+ prefix = "venus:app";
2230
+ syncDelay = 100;
2231
+ break;
2232
+ case "globalStorage":
2233
+ prefix = "venus:global";
2234
+ syncDelay = 100;
2235
+ break;
2236
+ default:
2237
+ throw new Error(`Unknown storage type: ${storageType}`);
2252
2238
  }
2253
- };
2254
-
2255
- // src/rooms/setupRoomNotifications.ts
2256
- function invokeCallbacks(callbacks, event, context) {
2257
- callbacks.forEach((callback) => {
2258
- try {
2259
- callback(event);
2260
- } catch (error) {
2261
- console.error(`[Venus SDK] Error in ${context} callback:`, error);
2262
- throw error;
2263
- }
2264
- });
2265
- }
2266
- function setupRoomNotifications(transport, getSubscriptions) {
2267
- return transport.onVenusMessage((message) => {
2268
- const subscriptions = getSubscriptions();
2269
- if (!subscriptions) {
2270
- return;
2271
- }
2272
- if (message.type === "H5_ROOM_DATA_UPDATED") {
2273
- const messageData = message.data;
2274
- const { roomId, roomData } = messageData;
2275
- if (!roomId) return;
2276
- const callbacks = subscriptions.data[roomId] || [];
2277
- const event = {
2278
- type: "H5_ROOM_DATA_UPDATED",
2279
- roomId,
2280
- roomData,
2281
- timestamp: messageData.timestamp
2282
- };
2283
- invokeCallbacks(callbacks, event, "room data");
2284
- }
2285
- if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
2286
- const messageData = message.data;
2287
- const { roomId } = messageData;
2288
- if (!roomId) return;
2289
- const callbacks = subscriptions.messages[roomId] || [];
2290
- const event = {
2291
- type: message.type,
2292
- roomId,
2293
- message: messageData.message,
2294
- timestamp: messageData.timestamp
2295
- };
2296
- invokeCallbacks(callbacks, event, "room message");
2297
- }
2298
- if (message.type === "app:h5:proposedMoveValidationUpdated") {
2299
- const messageData = message.data;
2300
- const { roomId } = messageData;
2301
- if (!roomId) return;
2302
- const callbacks = subscriptions.gameEvents[roomId] || [];
2303
- const event = {
2304
- type: "app:h5:proposedMoveValidationUpdated",
2305
- roomId,
2306
- proposedMoveData: messageData.proposedMoveData,
2307
- proposedMoveId: messageData.proposedMoveId,
2308
- changeType: messageData.changeType,
2309
- timestamp: messageData.timestamp
2310
- };
2311
- invokeCallbacks(callbacks, event, "game event");
2312
- }
2313
- });
2314
- }
2315
-
2316
- // src/rooms/RpcRoomsApi.ts
2317
- var RpcRoomsApi = class {
2318
- constructor(rpcClient) {
2319
- __publicField(this, "rpcClient");
2320
- __publicField(this, "subscriptions");
2321
- this.rpcClient = rpcClient;
2322
- this.subscriptions = {
2323
- data: {},
2324
- messages: {},
2325
- gameEvents: {}
2326
- };
2327
- }
2328
- /**
2329
- * Get the subscription state for external access (used by setupRoomNotifications)
2330
- */
2331
- getSubscriptions() {
2332
- return this.subscriptions;
2333
- }
2334
- /**
2335
- * Set up room notification routing from the transport
2336
- */
2337
- setupNotifications(transport) {
2338
- setupRoomNotifications(transport, () => this.getSubscriptions());
2339
- }
2340
- async createRoomAsync(options) {
2341
- const response = await this.rpcClient.call(
2342
- "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
2343
- {
2344
- options
2345
- }
2346
- );
2347
- if (response.success === false) {
2348
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
2349
- throw new Error(errorMessage);
2350
- }
2351
- const room = new VenusRoom(response.roomData);
2352
- return room;
2353
- }
2354
- async joinOrCreateRoomAsync(options) {
2355
- const response = await this.rpcClient.call(
2356
- "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
2357
- {
2358
- options
2359
- }
2360
- );
2361
- if (response.success === false) {
2362
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
2363
- throw new Error(errorMessage);
2364
- }
2365
- const room = new VenusRoom(response.value.roomData);
2366
- return {
2367
- action: response.value.action,
2368
- room,
2369
- playersJoined: response.value.playersJoined
2370
- };
2371
- }
2372
- async joinRoomByCodeAsync(roomCode) {
2373
- const response = await this.rpcClient.call(
2374
- "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
2375
- {
2376
- roomCode
2377
- }
2378
- );
2379
- if (response?.success === false) {
2380
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
2381
- throw new Error(errorMessage);
2382
- }
2383
- const room = new VenusRoom(response.roomData);
2384
- return room;
2385
- }
2386
- // Get user's rooms with optional filtering
2387
- async getUserRoomsAsync(options = {}) {
2388
- const response = await this.rpcClient.call(
2389
- "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
2390
- {
2391
- includeArchived: options.includeArchived ?? false
2392
- }
2393
- );
2394
- if (response?.success === false) {
2395
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
2396
- throw new Error(errorMessage);
2397
- }
2398
- const venusRooms = [];
2399
- for (const roomData of response.rooms) {
2400
- if (!roomData.id) {
2401
- console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
2402
- continue;
2403
- }
2404
- try {
2405
- const venusRoom = new VenusRoom(roomData);
2406
- venusRooms.push(venusRoom);
2407
- } catch (error) {
2408
- console.warn(
2409
- "[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
2410
- error,
2411
- roomData
2412
- );
2413
- }
2414
- }
2415
- return venusRooms;
2416
- }
2417
- async updateRoomDataAsync(room, updates, options = {}) {
2418
- const response = await this.rpcClient.call(
2419
- "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
2420
- {
2421
- roomId: room.id,
2422
- updates,
2423
- merge: options.merge ?? true
2424
- }
2425
- );
2426
- if (response?.success === false) {
2427
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
2428
- throw new Error(errorMessage);
2429
- }
2430
- }
2431
- async getRoomDataAsync(room) {
2432
- const response = await this.rpcClient.call(
2433
- "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
2434
- {
2435
- roomId: room.id
2436
- }
2437
- );
2438
- if (response?.success === false) {
2439
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
2440
- throw new Error(errorMessage);
2441
- }
2442
- return response.data;
2443
- }
2444
- async sendRoomMessageAsync(venusRoom, request) {
2445
- const response = await this.rpcClient.call(
2446
- "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
2447
- {
2448
- roomId: venusRoom.id,
2449
- message: request.message,
2450
- metadata: request.metadata
2451
- }
2452
- );
2453
- if (response?.success === false) {
2454
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
2455
- throw new Error(errorMessage);
2456
- }
2457
- return response.messageId;
2458
- }
2459
- async leaveRoomAsync(room) {
2460
- const response = await this.rpcClient.call(
2461
- "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
2462
- {
2463
- roomId: room.id
2464
- }
2465
- );
2466
- if (response?.success === false) {
2467
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
2468
- throw new Error(errorMessage);
2469
- }
2470
- }
2471
- async startRoomGameAsync(room, options = {}) {
2472
- const response = await this.rpcClient.call(
2473
- "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
2474
- {
2475
- roomId: room.id,
2476
- gameConfig: options.gameConfig ?? {},
2477
- turnOrder: options.turnOrder ?? null
2478
- }
2479
- );
2480
- if (response?.success === false) {
2481
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
2482
- throw new Error(errorMessage);
2483
- }
2484
- }
2485
- async proposeMoveAsync(room, proposalPayload) {
2486
- const response = await this.rpcClient.call(
2487
- "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
2488
- {
2489
- roomId: room.id,
2490
- gameSpecificState: proposalPayload.gameSpecificState,
2491
- moveType: proposalPayload.moveType,
2492
- clientContext: proposalPayload.clientContext,
2493
- clientProposalId: proposalPayload.clientProposalId
2494
- }
2495
- );
2496
- if (response?.success === false) {
2497
- const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
2498
- throw new Error(errorMessage);
2499
- }
2500
- return response.data;
2501
- }
2502
- async validateMoveAsync(_room, moveId, verdict) {
2503
- return {
2504
- success: true,
2505
- moveId,
2506
- isValid: verdict.isValid,
2507
- reason: verdict.reason
2508
- };
2509
- }
2510
- async subscribeAsync(room, options = {}) {
2511
- const roomId = room.id;
2512
- const existingData = this.subscriptions.data[roomId];
2513
- const existingMessages = this.subscriptions.messages[roomId];
2514
- const existingGameEvents = this.subscriptions.gameEvents[roomId];
2515
- const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
2516
- const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
2517
- const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
2518
- if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
2519
- try {
2520
- await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
2521
- roomId,
2522
- subscribeToData,
2523
- subscribeToMessages,
2524
- subscribeToProposedMoves
2525
- });
2526
- } catch (error) {
2527
- console.error("[Venus SDK] Failed to set up room subscription:", error);
2528
- throw error;
2529
- }
2530
- }
2531
- if (options.onData) {
2532
- if (!this.subscriptions.data[roomId]) {
2533
- this.subscriptions.data[roomId] = [];
2534
- }
2535
- this.subscriptions.data[roomId].push(options.onData);
2536
- }
2537
- if (options.onMessages) {
2538
- if (!this.subscriptions.messages[roomId]) {
2539
- this.subscriptions.messages[roomId] = [];
2540
- }
2541
- this.subscriptions.messages[roomId].push(options.onMessages);
2542
- }
2543
- if (options.onGameEvents) {
2544
- if (!this.subscriptions.gameEvents[roomId]) {
2545
- this.subscriptions.gameEvents[roomId] = [];
2546
- }
2547
- this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
2548
- }
2549
- let disposed = false;
2550
- return () => {
2551
- if (disposed) return;
2552
- disposed = true;
2553
- if (options.onData) {
2554
- const callbacks = this.subscriptions.data[roomId];
2555
- if (callbacks) {
2556
- const index = callbacks.indexOf(options.onData);
2557
- if (index > -1) {
2558
- callbacks.splice(index, 1);
2559
- }
2560
- }
2561
- }
2562
- if (options.onMessages) {
2563
- const callbacks = this.subscriptions.messages[roomId];
2564
- if (callbacks) {
2565
- const index = callbacks.indexOf(options.onMessages);
2566
- if (index > -1) {
2567
- callbacks.splice(index, 1);
2568
- }
2569
- }
2570
- }
2571
- if (options.onGameEvents) {
2572
- const callbacks = this.subscriptions.gameEvents[roomId];
2573
- if (callbacks) {
2574
- const index = callbacks.indexOf(options.onGameEvents);
2575
- if (index > -1) {
2576
- callbacks.splice(index, 1);
2577
- }
2578
- }
2579
- }
2580
- const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
2581
- if (!hasAnySubscriptions) {
2582
- this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
2583
- roomId
2584
- }).catch((error) => {
2585
- console.error("[Venus SDK] Failed to clean up room subscription:", error);
2586
- });
2587
- }
2588
- };
2589
- }
2590
- };
2591
-
2592
- // src/rooms/index.ts
2593
- function bindMethod(target, targetKey, source, sourceKey) {
2594
- const key = sourceKey ?? targetKey;
2595
- const fn = source?.[key];
2596
- if (typeof fn === "function") {
2597
- target[targetKey] = fn.bind(source);
2598
- return true;
2599
- }
2600
- return false;
2601
- }
2602
- function initializeRoomsApi(venusApi, host) {
2603
- const roomsApi = host?.rooms;
2604
- if (!roomsApi) {
2605
- console.warn(
2606
- "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
2607
- );
2608
- return;
2609
- }
2610
- const venus = venusApi;
2611
- const existingNamespace = venus.rooms || {};
2612
- const roomsNamespace = Object.assign({}, existingNamespace);
2613
- const namespaceBindings = [
2614
- ["createRoomAsync"],
2615
- ["joinOrCreateRoomAsync"],
2616
- ["joinRoomByCodeAsync"],
2617
- ["getUserRoomsAsync"],
2618
- ["subscribeAsync"],
2619
- ["updateRoomDataAsync"],
2620
- ["getRoomDataAsync"],
2621
- ["sendRoomMessageAsync"],
2622
- ["leaveRoomAsync"],
2623
- ["startRoomGameAsync"],
2624
- ["proposeMoveAsync"],
2625
- ["validateMoveAsync"]
2626
- ];
2627
- namespaceBindings.forEach(([targetKey, sourceKey]) => {
2628
- bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
2629
- });
2630
- venus.rooms = roomsNamespace;
2631
- }
2632
-
2633
- // src/storage/MockStorageApi.ts
2634
- function createMockStorageApi(storageType, appUrl) {
2635
- const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2636
- let prefix;
2637
- let syncDelay = 0;
2638
- switch (storageType) {
2639
- case "deviceCache":
2640
- prefix = "venus:app";
2641
- syncDelay = 0;
2642
- break;
2643
- case "appStorage":
2644
- prefix = "venus:app";
2645
- syncDelay = 100;
2646
- break;
2647
- case "globalStorage":
2648
- prefix = "venus:global";
2649
- syncDelay = 100;
2650
- break;
2651
- default:
2652
- throw new Error(`Unknown storage type: ${storageType}`);
2653
- }
2654
- prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2655
- return new MockStorageApi(prefix, syncDelay);
2239
+ prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2240
+ return new MockStorageApi(prefix, syncDelay);
2656
2241
  }
2657
2242
  var MockStorageApi = class {
2658
2243
  constructor(prefix, syncDelay) {
@@ -2863,20 +2448,24 @@ function initializeStorage(venusApiInstance, host) {
2863
2448
  venusApiInstance.globalStorage = host.globalStorage;
2864
2449
  }
2865
2450
 
2451
+ // src/simulation/utils.ts
2452
+ function sumContributions(contributions) {
2453
+ const totals = {};
2454
+ for (const profileId in contributions) {
2455
+ for (const entityId in contributions[profileId]) {
2456
+ const amount = contributions[profileId][entityId] || 0;
2457
+ totals[entityId] = (totals[entityId] || 0) + amount;
2458
+ }
2459
+ }
2460
+ return totals;
2461
+ }
2462
+
2866
2463
  // src/simulation/RpcSimulationApi.ts
2867
2464
  var RpcSimulationApi = class {
2868
2465
  constructor(rpcClient) {
2869
2466
  __publicField(this, "rpcClient");
2870
2467
  __publicField(this, "_simulationConfig", null);
2871
- __publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
2872
2468
  this.rpcClient = rpcClient;
2873
- this.rpcClient.onNotification(
2874
- "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
2875
- this.handleSimulationUpdate.bind(this)
2876
- );
2877
- }
2878
- isEnabled() {
2879
- return true;
2880
2469
  }
2881
2470
  async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2882
2471
  return this.rpcClient.call(
@@ -2888,47 +2477,14 @@ var RpcSimulationApi = class {
2888
2477
  }
2889
2478
  );
2890
2479
  }
2891
- async subscribeAsync(options) {
2892
- this.ensureValidSubscribeOptions(options);
2893
- const subscriptionId = generateId();
2894
- this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
2895
- try {
2896
- await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
2897
- subscriptionId,
2898
- entities: options.entities,
2899
- tags: options.tags,
2900
- activeRuns: options.activeRuns,
2901
- roomId: options.roomId
2902
- });
2903
- } catch (error) {
2904
- this.subscriptionCallbacks.delete(subscriptionId);
2905
- throw error;
2906
- }
2907
- let unsubscribed = false;
2908
- return () => {
2909
- if (unsubscribed) {
2910
- return;
2911
- }
2912
- unsubscribed = true;
2913
- this.subscriptionCallbacks.delete(subscriptionId);
2914
- void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
2915
- subscriptionId
2916
- }).catch((error) => {
2917
- console.error(
2918
- "[Venus SDK] Failed to unsubscribe simulation listener",
2919
- error
2920
- );
2921
- });
2922
- };
2480
+ sumContributions(contributions) {
2481
+ return sumContributions(contributions);
2923
2482
  }
2924
2483
  executeBatchOperationsAsync(operations, validateOnly) {
2925
- return this.rpcClient.call(
2926
- "H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
2927
- {
2928
- operations,
2929
- validateOnly
2930
- }
2931
- );
2484
+ return this.rpcClient.call("H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */, {
2485
+ operations,
2486
+ validateOnly
2487
+ });
2932
2488
  }
2933
2489
  async getAvailableItemsAsync(containerId, slotId) {
2934
2490
  const response = await this.rpcClient.call(
@@ -2951,23 +2507,17 @@ var RpcSimulationApi = class {
2951
2507
  );
2952
2508
  }
2953
2509
  assignItemToSlotAsync(containerId, slotId, itemId) {
2954
- return this.rpcClient.call(
2955
- "H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
2956
- {
2957
- containerId,
2958
- slotId,
2959
- itemId
2960
- }
2961
- );
2510
+ return this.rpcClient.call("H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */, {
2511
+ containerId,
2512
+ slotId,
2513
+ itemId
2514
+ });
2962
2515
  }
2963
2516
  removeItemFromSlotAsync(containerId, slotId) {
2964
- return this.rpcClient.call(
2965
- "H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
2966
- {
2967
- containerId,
2968
- slotId
2969
- }
2970
- );
2517
+ return this.rpcClient.call("H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */, {
2518
+ containerId,
2519
+ slotId
2520
+ });
2971
2521
  }
2972
2522
  async getSlotContainersAsync() {
2973
2523
  const response = await this.rpcClient.call(
@@ -2992,6 +2542,7 @@ var RpcSimulationApi = class {
2992
2542
  roomId
2993
2543
  }
2994
2544
  );
2545
+ console.log("[Venus SDK] getStateAsync", response);
2995
2546
  if (response.configuration) {
2996
2547
  this._simulationConfig = response.configuration;
2997
2548
  }
@@ -3003,10 +2554,9 @@ var RpcSimulationApi = class {
3003
2554
  }
3004
2555
  const config = await this.rpcClient.call(
3005
2556
  "H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
3006
- {
3007
- roomId
3008
- }
2557
+ {}
3009
2558
  );
2559
+ console.log("[Venus SDK] getConfigAsync", config);
3010
2560
  if (config) {
3011
2561
  this._simulationConfig = config;
3012
2562
  return config;
@@ -3014,17 +2564,14 @@ var RpcSimulationApi = class {
3014
2564
  throw new Error("No simulation configuration available");
3015
2565
  }
3016
2566
  executeRecipeAsync(recipeId, inputs, options) {
3017
- return this.rpcClient.call(
3018
- "H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
3019
- {
3020
- recipeId,
3021
- inputs,
3022
- roomId: options?.roomId,
3023
- batchAmount: options?.batchAmount,
3024
- allowPartialBatch: options?.allowPartialBatch,
3025
- entity: options?.entity
3026
- }
3027
- );
2567
+ return this.rpcClient.call("H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */, {
2568
+ recipeId,
2569
+ inputs,
2570
+ roomId: options?.roomId,
2571
+ batchAmount: options?.batchAmount,
2572
+ allowPartialBatch: options?.allowPartialBatch,
2573
+ entity: options?.entity
2574
+ });
3028
2575
  }
3029
2576
  collectRecipeAsync(runId) {
3030
2577
  return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
@@ -3032,12 +2579,9 @@ var RpcSimulationApi = class {
3032
2579
  });
3033
2580
  }
3034
2581
  getActiveRunsAsync(options) {
3035
- return this.rpcClient.call(
3036
- "H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
3037
- {
3038
- roomId: options?.roomId
3039
- }
3040
- );
2582
+ return this.rpcClient.call("H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */, {
2583
+ roomId: options?.roomId
2584
+ });
3041
2585
  }
3042
2586
  executeScopedRecipeAsync(recipeId, entity, inputs, options) {
3043
2587
  return this.rpcClient.call(
@@ -3096,63 +2640,594 @@ var RpcSimulationApi = class {
3096
2640
  }
3097
2641
  );
3098
2642
  }
3099
- async resolveFieldValueAsync(entityId, fieldPath, entity) {
3100
- const response = await this.rpcClient.call(
3101
- "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
3102
- {
3103
- entityId,
3104
- fieldPath,
3105
- entity
3106
- }
3107
- );
3108
- return response.value;
2643
+ async resolveFieldValueAsync(entityId, fieldPath, entity) {
2644
+ const response = await this.rpcClient.call(
2645
+ "H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
2646
+ {
2647
+ entityId,
2648
+ fieldPath,
2649
+ entity
2650
+ }
2651
+ );
2652
+ return response.value;
2653
+ }
2654
+ };
2655
+
2656
+ // src/simulation/MockSimulationApi.ts
2657
+ function generateAppIdentifier2() {
2658
+ if (typeof window === "undefined") return "unknown-app";
2659
+ const url = window.location.href;
2660
+ const match = url.match(/\/H5\/([^\/]+)/);
2661
+ return match ? match[1] : "unknown-app";
2662
+ }
2663
+ var MockSimulationApi = class {
2664
+ constructor(simulationConfig = null) {
2665
+ __publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
2666
+ // appIdentifier -> config
2667
+ __publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
2668
+ // appIdentifier -> config
2669
+ __publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
2670
+ // appIdentifier -> timers[]
2671
+ __publicField(this, "appId");
2672
+ __publicField(this, "providedSimulationConfig");
2673
+ this.appId = generateAppIdentifier2();
2674
+ this.providedSimulationConfig = simulationConfig;
2675
+ }
2676
+ sumContributions(contributions) {
2677
+ return sumContributions(contributions);
2678
+ }
2679
+ async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2680
+ this.log("validateSlotAssignmentAsync called:", {
2681
+ containerId,
2682
+ slotId,
2683
+ itemId
2684
+ });
2685
+ return { valid: true, message: "Mock validation successful" };
2686
+ }
2687
+ async executeBatchOperationsAsync(operations, validateOnly) {
2688
+ this.log("executeBatchOperationsAsync called:", {
2689
+ operations,
2690
+ validateOnly
2691
+ });
2692
+ return {
2693
+ success: true,
2694
+ results: operations.map(() => ({ success: true }))
2695
+ };
2696
+ }
2697
+ async getAvailableItemsAsync(containerId, slotId) {
2698
+ console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
2699
+ containerId,
2700
+ slotId
2701
+ });
2702
+ const appIdentifier = generateAppIdentifier2();
2703
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2704
+ const config = mockSimulationConfigs.get(appIdentifier) || {
2705
+ entities: {}
2706
+ };
2707
+ const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
2708
+ entityId,
2709
+ quantity: 1,
2710
+ metadata: entity.metadata,
2711
+ powerPreview: 100
2712
+ // Mock power value
2713
+ }));
2714
+ return availableItems;
2715
+ }
2716
+ async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
2717
+ this.log("calculatePowerPreviewAsync called:", {
2718
+ containerId,
2719
+ slotId,
2720
+ candidateItemId
2721
+ });
2722
+ return {
2723
+ currentPower: 1e3,
2724
+ previewPower: 1200,
2725
+ powerDelta: 200,
2726
+ breakdown: { base: 800, weapon: 200, armor: 200 }
2727
+ };
2728
+ }
2729
+ async getSlotContainersAsync() {
2730
+ this.log("getSlotContainersAsync called");
2731
+ const appIdentifier = this.appId;
2732
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2733
+ const config = mockSimulationConfigs.get(appIdentifier) || {
2734
+ entities: {}
2735
+ };
2736
+ const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
2737
+ entityId,
2738
+ slots: entity.metadata?.slots,
2739
+ isOwned: true
2740
+ // Mock: assume all containers are owned
2741
+ }));
2742
+ return containers;
2743
+ }
2744
+ async getSlotAssignmentsAsync(containerId) {
2745
+ this.log("getSlotAssignmentsAsync called for:", containerId);
2746
+ return [];
2747
+ }
2748
+ async resolveFieldValueAsync(entityId, fieldPath, entity) {
2749
+ this.log("resolveFieldValueAsync called:", {
2750
+ entityId,
2751
+ fieldPath,
2752
+ entity
2753
+ });
2754
+ const mockValues = {
2755
+ basePower: 850,
2756
+ weaponPower: 300,
2757
+ armorPower: 150,
2758
+ total_power: 1300,
2759
+ total_defense_power: 5e3
2760
+ };
2761
+ return mockValues[fieldPath] || 100;
2762
+ }
2763
+ async getEntityMetadataAsync(entityId) {
2764
+ this.log("getEntityMetadataAsync called for:", entityId);
2765
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2766
+ const appIdentifier = this.appId;
2767
+ const config = mockSimulationConfigs.get(
2768
+ appIdentifier
2769
+ ) || {
2770
+ entities: {}};
2771
+ const entity = config.entities[entityId];
2772
+ return entity?.metadata || {};
2773
+ }
2774
+ async collectRecipeAsync(runId) {
2775
+ this.log("collectRecipeAsync called:", { runId });
2776
+ const mockRewards = {
2777
+ cash: Math.floor(Math.random() * 1e3) + 500,
2778
+ experience: Math.floor(Math.random() * 50) + 25
2779
+ };
2780
+ return {
2781
+ success: true,
2782
+ runId,
2783
+ rewards: mockRewards,
2784
+ message: "Rewards collected successfully"
2785
+ };
2786
+ }
2787
+ executeRecipeAsync(recipeId, inputs, options) {
2788
+ this.log("executeRecipeAsync called:", {
2789
+ recipeId,
2790
+ inputs,
2791
+ options
2792
+ });
2793
+ const appIdentifier = this.appId;
2794
+ return this.executeRecipe(appIdentifier, recipeId, inputs);
2795
+ }
2796
+ async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
2797
+ this.log("executeScopedRecipeAsync called:", {
2798
+ recipeId,
2799
+ entity,
2800
+ inputs,
2801
+ roomId: options?.roomId,
2802
+ options
2803
+ });
2804
+ return {
2805
+ success: true,
2806
+ message: "Mock scoped recipe execution successful"
2807
+ };
2808
+ }
2809
+ async getActiveRunsAsync(options) {
2810
+ this.log("getActiveRunsAsync called:", options);
2811
+ const appIdentifier = this.appId;
2812
+ let state = this.mockSimulationStates.get(appIdentifier);
2813
+ if (!state) {
2814
+ state = await this.initializeSimulationState(appIdentifier);
2815
+ }
2816
+ return state.activeRuns || [];
2817
+ }
2818
+ async getAvailableRecipesAsync(options) {
2819
+ this.log("getAvailableRecipesAsync called:", options);
2820
+ const baseRecipes = [
2821
+ { id: "collect_resources", scope: "player", clientViewable: true },
2822
+ { id: "upgrade_equipment", scope: "player", clientViewable: true }
2823
+ ];
2824
+ if (options?.roomId) {
2825
+ baseRecipes.push(
2826
+ { id: "room_upgrade", scope: "room", clientViewable: true },
2827
+ { id: "cooperative_project", scope: "room", clientViewable: true }
2828
+ );
2829
+ }
2830
+ if (options?.includeActorRecipes && options?.roomId) {
2831
+ baseRecipes.push(
2832
+ { id: "trade_with_npc", scope: "actor", clientViewable: true },
2833
+ { id: "attack_monster", scope: "actor", clientViewable: true }
2834
+ );
2835
+ }
2836
+ return { success: true, recipes: baseRecipes };
2837
+ }
2838
+ async getBatchRecipeRequirementsAsync(recipes) {
2839
+ this.log("getBatchRecipeRequirementsAsync called:", {
2840
+ count: recipes?.length
2841
+ });
2842
+ const results = (recipes || []).map((q) => ({
2843
+ recipeId: q.recipeId,
2844
+ entity: q.entity || null,
2845
+ amount: q.batchAmount || 1,
2846
+ inputs: { cash: "BE:0" },
2847
+ canAfford: true,
2848
+ disabled: false
2849
+ }));
2850
+ return { success: true, results };
2851
+ }
2852
+ async getRecipeRequirementsAsync(recipe) {
2853
+ this.log("getRecipeRequirementsAsync called:", recipe);
2854
+ return {
2855
+ recipeId: recipe.recipeId,
2856
+ entity: recipe.entity || null,
2857
+ amount: recipe.batchAmount,
2858
+ inputs: { cash: "BE:0" },
2859
+ canAfford: true,
2860
+ disabled: false
2861
+ };
2862
+ }
2863
+ async triggerRecipeChainAsync(recipeId, options) {
2864
+ this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
2865
+ return {
2866
+ success: true,
2867
+ message: "Mock recipe chain triggered successfully"
2868
+ };
3109
2869
  }
3110
- handleSimulationUpdate(notification) {
3111
- if (!notification || !notification.subscriptionId) {
3112
- console.warn("[Venus SDK] Received malformed simulation update");
3113
- return;
2870
+ log(message, ...args) {
2871
+ console.log(`[Venus Sim Mock] ${message}`, args);
2872
+ }
2873
+ async executeRecipe(appIdentifier, recipeId, inputs) {
2874
+ this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
2875
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2876
+ const mockSimulationStates = this.mockSimulationStates;
2877
+ let config = mockSimulationConfigs.get(appIdentifier);
2878
+ let state = mockSimulationStates.get(appIdentifier);
2879
+ if (!config || !state) {
2880
+ state = await this.initializeSimulationState(appIdentifier);
2881
+ config = mockSimulationConfigs.get(appIdentifier);
2882
+ if (!config) {
2883
+ throw new Error("Failed to initialize simulation config");
2884
+ }
3114
2885
  }
3115
- const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
3116
- if (!callback) {
3117
- console.warn(
3118
- "[Venus SDK] Received update for unknown subscription:",
3119
- notification.subscriptionId
3120
- );
3121
- return;
2886
+ const recipe = config.recipes?.[recipeId];
2887
+ if (!recipe) {
2888
+ throw new Error(`Recipe ${recipeId} not found`);
3122
2889
  }
3123
- try {
3124
- callback(notification.updates);
3125
- } catch (error) {
3126
- console.error("[Venus SDK] Error in simulation subscription callback", error);
2890
+ if (state.disabledRecipes?.includes(recipeId)) {
2891
+ throw new Error(`Recipe ${recipeId} is disabled`);
2892
+ }
2893
+ if (recipe.inputs) {
2894
+ for (const [entityId, required] of Object.entries(recipe.inputs)) {
2895
+ const available = state.inventory[entityId] || 0;
2896
+ if (available < required) {
2897
+ throw new Error(
2898
+ `Insufficient ${entityId}: required ${required}, available ${available}`
2899
+ );
2900
+ }
2901
+ }
2902
+ }
2903
+ if (recipe.inputs) {
2904
+ for (const [entityId, input] of Object.entries(recipe.inputs)) {
2905
+ const inventoryValue = state.inventory[entityId] || 0;
2906
+ if (typeof input === "number" && typeof inventoryValue === "number") {
2907
+ state.inventory[entityId] = inventoryValue - input;
2908
+ }
2909
+ }
2910
+ }
2911
+ if (recipe.beginEffects) {
2912
+ this.applyEffects(state, recipe.beginEffects);
2913
+ }
2914
+ const runId = this.generateRunId();
2915
+ const now = Date.now();
2916
+ const expiresAt = now + (recipe.duration || 0);
2917
+ const run = {
2918
+ id: runId,
2919
+ recipeId,
2920
+ status: "running",
2921
+ startTime: now,
2922
+ expiresAt,
2923
+ inputs: recipe.inputs || {}
2924
+ };
2925
+ state.activeRuns.push(run);
2926
+ if (recipe.duration === 0) {
2927
+ this.completeRun(appIdentifier, runId);
2928
+ return { status: "completed", runId };
2929
+ } else {
2930
+ const mockActiveTimers = this.mockActiveTimers;
2931
+ const timer = setTimeout(() => {
2932
+ this.completeRun(appIdentifier, runId);
2933
+ }, recipe.duration);
2934
+ const timers = mockActiveTimers.get(appIdentifier) || [];
2935
+ timers.push(timer);
2936
+ mockActiveTimers.set(appIdentifier, timers);
2937
+ return {
2938
+ status: "running",
2939
+ runId,
2940
+ expiresAt: new Date(expiresAt).toISOString()
2941
+ };
3127
2942
  }
3128
2943
  }
3129
- ensureValidSubscribeOptions(options) {
3130
- if (typeof options !== "object" || options === null) {
3131
- throw new Error("Simulation subscribe requires an options object");
2944
+ async initializeSimulationState(appIdentifier) {
2945
+ this.log(`Initializing simulation state for ${appIdentifier}`);
2946
+ const providedSimulationConfig = this.providedSimulationConfig;
2947
+ const mockSimulationConfigs = this.mockSimulationConfigs;
2948
+ const mockSimulationStates = this.mockSimulationStates;
2949
+ const mockActiveTimers = this.mockActiveTimers;
2950
+ const config = providedSimulationConfig || {
2951
+ version: "1.0",
2952
+ entities: {},
2953
+ recipes: {}
2954
+ };
2955
+ mockSimulationConfigs.set(appIdentifier, config);
2956
+ const initialInventory = {};
2957
+ if (providedSimulationConfig && config.entities) {
2958
+ Object.keys(config.entities).forEach((entityId) => {
2959
+ initialInventory[entityId] = 0;
2960
+ });
3132
2961
  }
3133
- const opts = options;
3134
- if (typeof opts.onUpdate !== "function") {
3135
- throw new Error("Simulation subscribe requires an onUpdate callback");
2962
+ const state = {
2963
+ inventory: initialInventory,
2964
+ activeRuns: [],
2965
+ disabledRecipes: new Array()
2966
+ };
2967
+ if (config.recipes) {
2968
+ Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
2969
+ if (recipe.metadata?.startsDisabled) {
2970
+ state.disabledRecipes.push(recipeId);
2971
+ }
2972
+ });
3136
2973
  }
3137
- const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
3138
- if (!hasFilter) {
3139
- throw new Error(
3140
- "Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
2974
+ mockSimulationStates.set(appIdentifier, state);
2975
+ mockActiveTimers.set(appIdentifier, []);
2976
+ console.log(
2977
+ `[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
2978
+ state
2979
+ );
2980
+ if (config.recipes) {
2981
+ Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
2982
+ const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
2983
+ if (isAutoRestart && recipe.outputs) {
2984
+ this.log(`Found auto-restart recipe: ${recipeId}`, {
2985
+ topLevelAutoRestart: recipe.autoRestart,
2986
+ metadataAutoRestart: recipe.metadata?.autoRestart,
2987
+ hasOutputs: !!recipe.outputs,
2988
+ duration: recipe.duration
2989
+ });
2990
+ const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
2991
+ if (condition && condition.entity) {
2992
+ const currentAmount = initialInventory[condition.entity] || 0;
2993
+ if (currentAmount < condition.maxValue) {
2994
+ console.log(
2995
+ `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
2996
+ {
2997
+ currentAmount,
2998
+ maxValue: condition.maxValue,
2999
+ entity: condition.entity
3000
+ }
3001
+ );
3002
+ setTimeout(() => {
3003
+ this.executeRecipe(appIdentifier, recipeId, {});
3004
+ }, 1e3);
3005
+ }
3006
+ } else {
3007
+ console.log(
3008
+ `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
3009
+ );
3010
+ setTimeout(() => {
3011
+ this.executeRecipe(appIdentifier, recipeId, {});
3012
+ }, 1e3);
3013
+ }
3014
+ }
3015
+ });
3016
+ }
3017
+ return state;
3018
+ }
3019
+ generateRunId() {
3020
+ return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
3021
+ }
3022
+ completeRun(appIdentifier, runId) {
3023
+ this.log(`Completing run ${runId} for ${appIdentifier}`);
3024
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3025
+ const mockSimulationStates = this.mockSimulationStates;
3026
+ const config = mockSimulationConfigs.get(appIdentifier);
3027
+ const state = mockSimulationStates.get(appIdentifier);
3028
+ if (!config || !state) return;
3029
+ const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
3030
+ if (runIndex === -1) return;
3031
+ const run = state.activeRuns[runIndex];
3032
+ const recipe = config.recipes?.[run.recipeId];
3033
+ if (!recipe) return;
3034
+ const outputs = {};
3035
+ const rng = this.createSeededRandom(runId);
3036
+ if (recipe.outputs) {
3037
+ for (const [entityId, value] of Object.entries(recipe.outputs)) {
3038
+ if (typeof value === "number") {
3039
+ outputs[entityId] = value;
3040
+ } else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
3041
+ outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
3042
+ }
3043
+ }
3044
+ }
3045
+ for (const [entityId, amount] of Object.entries(outputs)) {
3046
+ state.inventory[entityId] = (state.inventory[entityId] || 0) + amount;
3047
+ }
3048
+ if (recipe.endEffects) {
3049
+ this.applyEffects(state, recipe.endEffects);
3050
+ }
3051
+ run.status = "completed";
3052
+ run.outputs = outputs;
3053
+ state.activeRuns.splice(runIndex, 1);
3054
+ const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
3055
+ if (isAutoRestart) {
3056
+ console.log(
3057
+ `[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
3058
+ {
3059
+ topLevelAutoRestart: recipe.autoRestart,
3060
+ metadataAutoRestart: recipe.metadata?.autoRestart,
3061
+ hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
3062
+ }
3141
3063
  );
3064
+ const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
3065
+ if (condition) {
3066
+ const currentAmount = state.inventory[condition.entity] || 0;
3067
+ if (currentAmount < condition.maxValue) {
3068
+ console.log(
3069
+ `[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
3070
+ {
3071
+ currentAmount,
3072
+ maxValue: condition.maxValue,
3073
+ entity: condition.entity
3074
+ }
3075
+ );
3076
+ setTimeout(() => {
3077
+ this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3078
+ }, 1e3);
3079
+ }
3080
+ } else {
3081
+ console.log(
3082
+ `[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
3083
+ );
3084
+ setTimeout(() => {
3085
+ this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3086
+ }, 1e3);
3087
+ }
3142
3088
  }
3089
+ console.log(
3090
+ `[Venus Simulation Mock] Completed run ${runId}, outputs:`,
3091
+ outputs
3092
+ );
3093
+ }
3094
+ createSeededRandom(seed) {
3095
+ let hash = 0;
3096
+ for (let i = 0; i < seed.length; i++) {
3097
+ const char = seed.charCodeAt(i);
3098
+ hash = (hash << 5) - hash + char;
3099
+ hash = hash & hash;
3100
+ }
3101
+ return () => {
3102
+ hash = (hash * 9301 + 49297) % 233280;
3103
+ return hash / 233280;
3104
+ };
3105
+ }
3106
+ applyEffects(state, effects) {
3107
+ if (!effects || !Array.isArray(effects)) return;
3108
+ for (const effect of effects) {
3109
+ switch (effect.type) {
3110
+ case "set":
3111
+ state.inventory[effect.target] = effect.value;
3112
+ console.log(
3113
+ `[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
3114
+ );
3115
+ break;
3116
+ case "add":
3117
+ state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
3118
+ console.log(
3119
+ `[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
3120
+ );
3121
+ break;
3122
+ case "multiply":
3123
+ state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
3124
+ console.log(
3125
+ `[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
3126
+ );
3127
+ break;
3128
+ case "min":
3129
+ state.inventory[effect.target] = Math.max(
3130
+ state.inventory[effect.target] || 0,
3131
+ effect.value
3132
+ );
3133
+ console.log(
3134
+ `[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
3135
+ );
3136
+ break;
3137
+ case "max":
3138
+ state.inventory[effect.target] = Math.min(
3139
+ state.inventory[effect.target] || 0,
3140
+ effect.value
3141
+ );
3142
+ console.log(
3143
+ `[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
3144
+ );
3145
+ break;
3146
+ case "enable_recipe":
3147
+ if (state.disabledRecipes?.includes(effect.target)) {
3148
+ state.disabledRecipes = state.disabledRecipes.filter(
3149
+ (r) => r !== effect.target
3150
+ );
3151
+ console.log(
3152
+ `[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
3153
+ );
3154
+ }
3155
+ break;
3156
+ case "disable_recipe":
3157
+ if (!state.disabledRecipes) state.disabledRecipes = [];
3158
+ if (!state.disabledRecipes.includes(effect.target)) {
3159
+ state.disabledRecipes.push(effect.target);
3160
+ console.log(
3161
+ `[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
3162
+ );
3163
+ }
3164
+ break;
3165
+ case "trigger_recipe":
3166
+ console.log(
3167
+ `[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
3168
+ );
3169
+ break;
3170
+ default:
3171
+ console.warn(
3172
+ `[Venus Simulation Mock] Unknown effect type: ${effect.type}`
3173
+ );
3174
+ }
3175
+ }
3176
+ }
3177
+ async getConfigAsync() {
3178
+ console.log("[Venus Simulation Mock] getConfigAsync called");
3179
+ const appIdentifier = this.appId;
3180
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3181
+ const config = mockSimulationConfigs.get(appIdentifier) || {
3182
+ version: "1.0",
3183
+ entities: {},
3184
+ recipes: {}
3185
+ };
3186
+ return config;
3187
+ }
3188
+ async getStateAsync(roomId) {
3189
+ this.log("getStateAsync called:", roomId);
3190
+ const appIdentifier = this.appId;
3191
+ const mockSimulationStates = this.mockSimulationStates;
3192
+ let state = mockSimulationStates.get(appIdentifier);
3193
+ if (!state) {
3194
+ state = await this.initializeSimulationState(appIdentifier);
3195
+ }
3196
+ const mockSimulationConfigs = this.mockSimulationConfigs;
3197
+ return {
3198
+ ...state,
3199
+ roomId,
3200
+ configuration: mockSimulationConfigs.get(appIdentifier)
3201
+ };
3202
+ }
3203
+ async assignItemToSlotAsync(containerId, slotId, itemId) {
3204
+ this.log("assignItemToSlotAsync called:", {
3205
+ containerId,
3206
+ slotId,
3207
+ itemId
3208
+ });
3209
+ return { success: true, message: "Mock assignment successful" };
3210
+ }
3211
+ async removeItemFromSlotAsync(containerId, slotId) {
3212
+ this.log("removeItemFromSlotAsync called:", {
3213
+ containerId,
3214
+ slotId
3215
+ });
3216
+ return { success: true, message: "Mock removal successful" };
3143
3217
  }
3144
3218
  };
3145
3219
 
3146
3220
  // src/simulation/index.ts
3147
3221
  function initializeSimulation(venusApi, host) {
3222
+ console.log("[Venus SDK] Initializing new Simulation Api");
3148
3223
  venusApi.simulation = {
3149
3224
  isEnabled: () => true
3150
3225
  };
3151
3226
  venusApi.simulation.getConfigAsync = () => {
3152
3227
  return host.simulation.getConfigAsync();
3153
3228
  };
3154
- venusApi.simulation.getStateAsync = (roomId) => {
3155
- return host.simulation.getStateAsync(roomId);
3229
+ venusApi.simulation.getStateAsync = (options) => {
3230
+ return host.simulation.getStateAsync(options?.roomId);
3156
3231
  };
3157
3232
  venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
3158
3233
  return host.simulation.executeRecipeAsync(recipeId, inputs, options);
@@ -3163,17 +3238,31 @@ function initializeSimulation(venusApi, host) {
3163
3238
  venusApi.simulation.collectRecipeAsync = (runId) => {
3164
3239
  return host.simulation.collectRecipeAsync(runId);
3165
3240
  };
3166
- venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
3167
- return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
3241
+ venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, roomId, options) => {
3242
+ return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, {
3243
+ roomId,
3244
+ ...options
3245
+ });
3168
3246
  };
3169
- venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
3170
- return host.simulation.triggerRecipeChainAsync(recipeId, options);
3247
+ venusApi.simulation.triggerRecipeChainAsync = (recipeId, context, roomId) => {
3248
+ return host.simulation.triggerRecipeChainAsync(recipeId, {
3249
+ context,
3250
+ roomId
3251
+ });
3171
3252
  };
3172
- venusApi.simulation.getAvailableRecipesAsync = async (options) => {
3173
- return host.simulation.getAvailableRecipesAsync(options);
3253
+ venusApi.simulation.getAvailableRecipesAsync = async (roomId, includeActorRecipes) => {
3254
+ const result = await host.simulation.getAvailableRecipesAsync({
3255
+ roomId,
3256
+ includeActorRecipes
3257
+ });
3258
+ return result.recipes;
3174
3259
  };
3175
- venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
3176
- return host.simulation.getRecipeRequirementsAsync(recipe);
3260
+ venusApi.simulation.getRecipeRequirementsAsync = (recipeId, entity, amount) => {
3261
+ return host.simulation.getRecipeRequirementsAsync({
3262
+ recipeId,
3263
+ entity,
3264
+ batchAmount: amount
3265
+ });
3177
3266
  };
3178
3267
  venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
3179
3268
  return host.simulation.getBatchRecipeRequirementsAsync(recipes);
@@ -3216,6 +3305,9 @@ function initializeSimulation(venusApi, host) {
3216
3305
  itemId
3217
3306
  );
3218
3307
  };
3308
+ venusApi.simulation.sumContributions = (contributions) => {
3309
+ return host.simulation.sumContributions(contributions);
3310
+ };
3219
3311
  }
3220
3312
 
3221
3313
  // src/time/utils.ts
@@ -3234,11 +3326,9 @@ function isPacificDaylightTime(date) {
3234
3326
 
3235
3327
  // src/time/HostTimeApi.ts
3236
3328
  var HostTimeApi = class {
3237
- constructor(rpcClient, venusApi) {
3329
+ constructor(rpcClient) {
3238
3330
  __publicField(this, "rpcClient");
3239
- __publicField(this, "venusApi");
3240
3331
  this.rpcClient = rpcClient;
3241
- this.venusApi = venusApi;
3242
3332
  }
3243
3333
  async requestTimeAsync() {
3244
3334
  const response = await this.rpcClient.call(
@@ -3248,7 +3338,13 @@ var HostTimeApi = class {
3248
3338
  return response;
3249
3339
  }
3250
3340
  formatTime(timestamp, options) {
3251
- const locale = this.venusApi.getLocale();
3341
+ let locale = "en-US";
3342
+ const windowVenus = window.venus;
3343
+ if (windowVenus._config.locale) {
3344
+ locale = windowVenus._config.locale;
3345
+ } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3346
+ locale = windowVenus._config.environment.browserInfo.language;
3347
+ }
3252
3348
  const date = new Date(timestamp);
3253
3349
  const dateTimeOptions = {
3254
3350
  dateStyle: options.dateStyle || "medium",
@@ -3260,7 +3356,13 @@ var HostTimeApi = class {
3260
3356
  }
3261
3357
  formatNumber(value, options) {
3262
3358
  try {
3263
- const locale = this.venusApi.getLocale();
3359
+ let locale = "en-US";
3360
+ const windowVenus = window.venus;
3361
+ if (windowVenus._config.locale) {
3362
+ locale = windowVenus._config.locale;
3363
+ } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3364
+ locale = windowVenus._config.environment.browserInfo.language;
3365
+ }
3264
3366
  const numberOptions = {
3265
3367
  style: options?.style || "decimal",
3266
3368
  minimumFractionDigits: options?.minimumFractionDigits || 0,
@@ -3323,17 +3425,18 @@ var MockTimeApi = class {
3323
3425
  this.venusApi = venusApi;
3324
3426
  }
3325
3427
  formatNumber(value, options) {
3326
- const locale = this.venusApi.getLocale();
3428
+ const locale = this.getLocale();
3327
3429
  const numberOptions = {
3328
3430
  style: options?.style || "decimal",
3329
3431
  minimumFractionDigits: options?.minimumFractionDigits || 0,
3330
3432
  maximumFractionDigits: options?.maximumFractionDigits || 2,
3331
3433
  ...options
3332
3434
  };
3435
+ console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
3333
3436
  return value.toLocaleString(locale, numberOptions);
3334
3437
  }
3335
3438
  formatTime(timestamp, options) {
3336
- const locale = this.venusApi.getLocale();
3439
+ const locale = this.getLocale();
3337
3440
  const date = new Date(timestamp);
3338
3441
  const dateTimeOptions = {
3339
3442
  dateStyle: options.dateStyle || "medium",
@@ -3341,9 +3444,13 @@ var MockTimeApi = class {
3341
3444
  hour12: options.hour12 !== void 0 ? options.hour12 : true,
3342
3445
  ...options
3343
3446
  };
3447
+ console.log(
3448
+ `[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
3449
+ );
3344
3450
  return date.toLocaleString(locale, dateTimeOptions);
3345
3451
  }
3346
3452
  async getFutureTimeAsync(options) {
3453
+ console.log("[Venus Mock] Getting future time with options:", options);
3347
3454
  const timeInfo = await this.requestTimeAsync();
3348
3455
  const serverTime = new Date(timeInfo.serverTime);
3349
3456
  const result = new Date(serverTime);
@@ -3388,6 +3495,7 @@ var MockTimeApi = class {
3388
3495
  return result.getTime();
3389
3496
  }
3390
3497
  async requestTimeAsync() {
3498
+ console.log("[Venus Mock] Requesting time");
3391
3499
  await createMockDelay(MOCK_DELAYS.short);
3392
3500
  const venusApi = this.venusApi;
3393
3501
  const mockOffset = venusApi._mock.serverTimeOffset || 2500;
@@ -3401,8 +3509,23 @@ var MockTimeApi = class {
3401
3509
  formattedTime: new Date(localTime).toISOString(),
3402
3510
  locale: venusApi._mock.user?.locale || "en-US"
3403
3511
  };
3512
+ console.log("[Venus Mock] Time response:", {
3513
+ serverTime: new Date(timeInfo.serverTime).toISOString(),
3514
+ localTime: new Date(timeInfo.localTime).toISOString(),
3515
+ timezoneOffset: timeInfo.timezoneOffset
3516
+ });
3404
3517
  return timeInfo;
3405
3518
  }
3519
+ getLocale() {
3520
+ const venusApi = this.venusApi;
3521
+ let locale = "en-US";
3522
+ if (venusApi._mock.user && venusApi._mock.user.locale) {
3523
+ locale = venusApi._mock.user.locale;
3524
+ } else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
3525
+ locale = venusApi._mock.environment.browserInfo.language;
3526
+ }
3527
+ return locale;
3528
+ }
3406
3529
  };
3407
3530
 
3408
3531
  // src/time/index.ts
@@ -3422,176 +3545,11 @@ function initializeTime(venusApi, host) {
3422
3545
  }
3423
3546
 
3424
3547
  // src/version.ts
3425
- var SDK_VERSION = "3.1.2-beta.1";
3426
-
3427
- // src/shared-assets/embeddedLibrariesManifest.ts
3428
- var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
3429
- var EMBEDDED_LIBRARIES = [
3430
- {
3431
- libraryKey: "phaser@3.90.0",
3432
- assetKey: "library:phaser@3.90.0",
3433
- packageName: "phaser",
3434
- version: "3.90.0",
3435
- globalVar: "Phaser",
3436
- cdnPath: "phaser/3.90.0/phaser.min.js",
3437
- moduleSpecifiers: [{ match: "exact", value: "phaser" }],
3438
- loadStage: 0,
3439
- enabled: true
3440
- },
3441
- {
3442
- libraryKey: "react@18.3.1",
3443
- assetKey: "library:react@18.3.1",
3444
- packageName: "react",
3445
- version: "18.3.1",
3446
- globalVar: "React",
3447
- cdnPath: "react/18.3.1/react.production.min.js",
3448
- moduleSpecifiers: [
3449
- { match: "exact", value: "react", behavior: "namespace" },
3450
- { match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
3451
- {
3452
- match: "exact",
3453
- value: "react/jsx-dev-runtime",
3454
- behavior: "react-jsx-dev-runtime"
3455
- }
3456
- ],
3457
- loadStage: 0,
3458
- // Must load before ReactDOM
3459
- enabled: true
3460
- },
3461
- {
3462
- libraryKey: "react-dom@18.3.1",
3463
- assetKey: "library:react-dom@18.3.1",
3464
- packageName: "react-dom",
3465
- version: "18.3.1",
3466
- globalVar: "ReactDOM",
3467
- cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
3468
- moduleSpecifiers: [
3469
- { match: "exact", value: "react-dom", behavior: "namespace" },
3470
- { match: "exact", value: "react-dom/client", behavior: "namespace" }
3471
- ],
3472
- loadStage: 1,
3473
- // Depends on React (stage 0)
3474
- enabled: true
3475
- },
3476
- {
3477
- libraryKey: "three@0.170.0",
3478
- assetKey: "library:three@0.170.0",
3479
- packageName: "three",
3480
- version: "0.170.0",
3481
- globalVar: "THREE",
3482
- cdnPath: "three/r170/three.min.js",
3483
- moduleSpecifiers: [
3484
- { match: "exact", value: "three", behavior: "namespace" },
3485
- { match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
3486
- ],
3487
- loadStage: 0,
3488
- enabled: true
3489
- },
3490
- {
3491
- libraryKey: "matter-js@0.19.0",
3492
- assetKey: "library:matter-js@0.19.0",
3493
- packageName: "matter-js",
3494
- version: "0.19.0",
3495
- globalVar: "Matter",
3496
- cdnPath: "matter-js/0.19.0/matter.min.js",
3497
- moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
3498
- loadStage: 0,
3499
- enabled: true
3500
- },
3501
- {
3502
- libraryKey: "inkjs@2.2.0",
3503
- assetKey: "library:inkjs@2.2.0",
3504
- packageName: "inkjs",
3505
- version: "2.2.0",
3506
- globalVar: "inkjs",
3507
- cdnPath: "inkjs/2.2.0/ink.min.js",
3508
- moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
3509
- loadStage: 0,
3510
- enabled: true
3511
- },
3512
- {
3513
- libraryKey: "zustand@5.0.3",
3514
- assetKey: "library:zustand@5.0.3",
3515
- packageName: "zustand",
3516
- version: "5.0.3",
3517
- globalVar: "zustand",
3518
- cdnPath: "zustand/5.0.3/zustand.min.js",
3519
- moduleSpecifiers: [
3520
- { match: "exact", value: "zustand" },
3521
- { match: "exact", value: "zustand/middleware" }
3522
- ],
3523
- loadStage: 0,
3524
- enabled: true
3525
- },
3526
- {
3527
- libraryKey: "ammo.js@2024.11",
3528
- assetKey: "library:ammo.js@2024.11",
3529
- packageName: "ammo.js",
3530
- version: "2024.11",
3531
- globalVar: "Ammo",
3532
- cdnPath: "ammo/2024.11/ammo.js",
3533
- moduleSpecifiers: [
3534
- { match: "exact", value: "ammo.js" },
3535
- { match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
3536
- ],
3537
- loadStage: 0,
3538
- enabled: false
3539
- // Not ready yet - WASM loading needs additional work
3540
- }
3541
- ];
3542
- var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
3543
- (acc, lib) => {
3544
- acc[lib.libraryKey] = lib;
3545
- return acc;
3546
- },
3547
- {}
3548
- );
3549
- var MODULE_TO_LIBRARY_SPECIFIERS = EMBEDDED_LIBRARIES.filter(
3550
- (lib) => lib.enabled
3551
- ).flatMap(
3552
- (lib) => lib.moduleSpecifiers.map((specifier) => ({
3553
- ...specifier,
3554
- libraryKey: lib.libraryKey
3555
- }))
3556
- );
3557
- function getLibraryDefinition(libraryKey) {
3558
- const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
3559
- if (!definition) {
3560
- const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
3561
- throw new Error(
3562
- `Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
3563
- );
3564
- }
3565
- return definition;
3566
- }
3548
+ var SDK_VERSION = "3.0.4";
3567
3549
 
3568
- // src/shared-assets/base64Utils.ts
3569
- function base64ToArrayBuffer(base64) {
3570
- const binaryString = atob(base64);
3571
- const len = binaryString.length;
3572
- const bytes = new Uint8Array(len);
3573
- for (let i = 0; i < len; i++) {
3574
- bytes[i] = binaryString.charCodeAt(i);
3575
- }
3576
- return bytes.buffer;
3577
- }
3578
- function base64ToUtf8(base64) {
3579
- if (typeof TextDecoder !== "undefined") {
3580
- const decoder = new TextDecoder("utf-8");
3581
- const buffer = base64ToArrayBuffer(base64);
3582
- return decoder.decode(new Uint8Array(buffer));
3583
- }
3584
- if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
3585
- const BufferCtor = globalThis.Buffer;
3586
- return BufferCtor.from(base64, "base64").toString("utf-8");
3587
- }
3588
- const binaryString = atob(base64);
3589
- let result = "";
3590
- for (let i = 0; i < binaryString.length; i++) {
3591
- result += String.fromCharCode(binaryString.charCodeAt(i));
3592
- }
3593
- return decodeURIComponent(escape(result));
3594
- }
3550
+ // src/shared-assets/consts.ts
3551
+ var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
3552
+ var CharacterAssetsCdnPath = "burger-time/Character.stow";
3595
3553
 
3596
3554
  // src/shared-assets/RpcSharedAssetsApi.ts
3597
3555
  var RpcSharedAssetsApi = class {
@@ -3601,48 +3559,46 @@ var RpcSharedAssetsApi = class {
3601
3559
  this.rpcClient = rpcClient;
3602
3560
  this.venusApi = venusApi;
3603
3561
  }
3604
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3562
+ async loadBurgerTimeAssetsBundle() {
3605
3563
  try {
3606
3564
  const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3607
- assetKey: bundleKey
3565
+ assetKey: "burgerTimeCoreBundle"
3608
3566
  });
3609
3567
  return base64ToArrayBuffer(response.base64Data);
3610
3568
  } catch (err) {
3611
3569
  try {
3612
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3570
+ const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
3613
3571
  return await blob.arrayBuffer();
3614
3572
  } catch (e) {
3615
- throw new Error(`Failed to load ${bundleKey}`);
3573
+ throw new Error("Failed to load burgerTimeAssetsBundle");
3616
3574
  }
3617
3575
  }
3618
3576
  }
3619
- async loadLibraryCode(libraryKey) {
3620
- const definition = getLibraryDefinition(libraryKey);
3577
+ async loadCharactersBundle() {
3621
3578
  try {
3622
3579
  const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3623
- assetKey: definition.assetKey
3580
+ assetKey: "characters"
3624
3581
  });
3625
- return base64ToUtf8(response.base64Data);
3582
+ return base64ToArrayBuffer(response.base64Data);
3626
3583
  } catch (err) {
3627
- console.error(
3628
- `[Venus Libraries] Failed to load ${libraryKey} from host via RPC:`,
3629
- err
3630
- );
3631
- console.warn(
3632
- `[Venus Libraries] Falling back to CDN for ${libraryKey}. This may indicate an asset packaging issue.`
3633
- );
3634
3584
  try {
3635
- const cdnUrl = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3636
- const response = await this.venusApi.cdn.fetchFromCdn(cdnUrl);
3637
- return await response.text();
3638
- } catch (cdnError) {
3639
- throw new Error(
3640
- `Failed to load embedded library ${libraryKey}: RPC failed, CDN fallback failed: ${cdnError.message}`
3641
- );
3585
+ const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
3586
+ return await blob.arrayBuffer();
3587
+ } catch (e) {
3588
+ throw new Error("Failed to load charactersBundle");
3642
3589
  }
3643
3590
  }
3644
3591
  }
3645
3592
  };
3593
+ function base64ToArrayBuffer(base64) {
3594
+ const binaryString = atob(base64);
3595
+ const len = binaryString.length;
3596
+ const bytes = new Uint8Array(len);
3597
+ for (let i = 0; i < len; i++) {
3598
+ bytes[i] = binaryString.charCodeAt(i);
3599
+ }
3600
+ return bytes.buffer;
3601
+ }
3646
3602
 
3647
3603
  // src/shared-assets/MockSharedAssetsApi.ts
3648
3604
  var MockSharedAssetsApi = class {
@@ -3650,118 +3606,57 @@ var MockSharedAssetsApi = class {
3650
3606
  __publicField(this, "venusApi");
3651
3607
  this.venusApi = venusApi;
3652
3608
  }
3653
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3654
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3609
+ async loadBurgerTimeAssetsBundle() {
3610
+ const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
3655
3611
  return await blob.arrayBuffer();
3656
3612
  }
3657
- async loadLibraryCode(libraryKey) {
3658
- const definition = getLibraryDefinition(libraryKey);
3659
- const url = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3660
- const response = await this.venusApi.cdn.fetchFromCdn(url);
3661
- return await response.text();
3613
+ async loadCharactersBundle() {
3614
+ const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
3615
+ return await blob.arrayBuffer();
3662
3616
  }
3663
3617
  };
3664
3618
 
3665
- // src/leaderboard/utils.ts
3666
- var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
3667
- var HASH_ALGORITHM_NODE = "sha256";
3668
- async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
3669
- const payload = `score:${score}|duration:${duration}|token:${token}`;
3670
- const fullPayload = `${payload}|nonce:${sealingNonce}`;
3671
- const encoder = new TextEncoder();
3672
- const keyData = encoder.encode(sealingSecret);
3673
- const messageData = encoder.encode(fullPayload);
3674
- const cryptoKey = await crypto.subtle.importKey(
3675
- "raw",
3676
- keyData,
3677
- { name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
3678
- false,
3679
- ["sign"]
3680
- );
3681
- const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
3682
- return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
3683
- }
3684
-
3685
3619
  // src/leaderboard/RpcLeaderboardApi.ts
3686
3620
  var RpcLeaderboardApi = class {
3687
3621
  constructor(rpcClient) {
3688
3622
  __publicField(this, "rpcClient");
3689
- /** Cache of score tokens for automatic hash computation */
3690
- __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3691
3623
  this.rpcClient = rpcClient;
3692
3624
  }
3693
- /**
3694
- * Create a score token for submitting a score.
3695
- * Token is cached for automatic hash computation if score sealing is enabled.
3696
- *
3697
- * @param mode - Optional game mode
3698
- * @returns Score token with sealing data if enabled
3699
- */
3700
- async createScoreToken(mode) {
3701
- const token = await this.rpcClient.call(
3702
- "H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
3625
+ startRun(mode) {
3626
+ return this.rpcClient.call(
3627
+ "H5_LEADERBOARD_START_RUN" /* H5_LEADERBOARD_START_RUN */,
3703
3628
  mode ? { mode } : {}
3704
3629
  );
3705
- this.tokenCache.set(token.token, token);
3706
- return token;
3707
3630
  }
3708
- /**
3709
- * Submit a score to the leaderboard.
3710
- * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3711
- *
3712
- * @param params - Score submission parameters
3713
- * @returns Submission result with acceptance status and rank
3714
- * @throws Error if token not found in cache
3715
- */
3716
- async submitScore(params) {
3717
- let hash;
3718
- if (params.token) {
3719
- const cachedToken = this.tokenCache.get(params.token);
3720
- if (!cachedToken) {
3721
- throw new Error(
3722
- "Invalid token: not found in cache. Did you call createScoreToken() first?"
3723
- );
3724
- }
3725
- if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3726
- hash = await computeScoreHash(
3727
- params.score,
3728
- params.duration,
3729
- params.token,
3730
- cachedToken.sealingNonce,
3731
- cachedToken.sealingSecret
3732
- );
3733
- }
3734
- this.tokenCache.delete(params.token);
3735
- }
3631
+ submitScore(sessionId, score, durationSec, options) {
3736
3632
  return this.rpcClient.call(
3737
3633
  "H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
3738
3634
  {
3739
- token: params.token,
3740
- score: params.score,
3741
- duration: params.duration,
3742
- mode: params.mode,
3743
- telemetry: params.telemetry,
3744
- metadata: params.metadata,
3745
- hash
3746
- // undefined if no sealing, computed if sealing enabled
3635
+ sessionId,
3636
+ score,
3637
+ durationSec,
3638
+ mode: options?.mode,
3639
+ telemetry: options?.telemetry,
3640
+ metadata: options?.metadata,
3641
+ hash: options?.hash
3747
3642
  }
3748
3643
  );
3749
3644
  }
3750
- getPagedScores(options) {
3645
+ getLeaderboard(options) {
3751
3646
  return this.rpcClient.call(
3752
- "H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
3647
+ "H5_LEADERBOARD_GET" /* H5_LEADERBOARD_GET */,
3753
3648
  options ?? {}
3754
3649
  );
3755
3650
  }
3756
- getMyRank(options) {
3651
+ getPlayerStats(options) {
3757
3652
  return this.rpcClient.call(
3758
- "H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
3653
+ "H5_LEADERBOARD_GET_PLAYER_STATS" /* H5_LEADERBOARD_GET_PLAYER_STATS */,
3759
3654
  options ?? {}
3760
3655
  );
3761
3656
  }
3762
- getPodiumScores(options) {
3657
+ getLeaderboardHighlight(options) {
3763
3658
  return this.rpcClient.call(
3764
- "H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
3659
+ "H5_LEADERBOARD_GET_HIGHLIGHT" /* H5_LEADERBOARD_GET_HIGHLIGHT */,
3765
3660
  options ?? {}
3766
3661
  );
3767
3662
  }
@@ -3770,31 +3665,17 @@ var RpcLeaderboardApi = class {
3770
3665
  // src/leaderboard/MockLeaderboardApi.ts
3771
3666
  var MockLeaderboardApi = class {
3772
3667
  constructor(options) {
3773
- __publicField(this, "tokens", /* @__PURE__ */ new Map());
3774
- /** Cache of score tokens for automatic hash computation */
3775
- __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3668
+ __publicField(this, "sessions", /* @__PURE__ */ new Map());
3776
3669
  __publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
3777
- __publicField(this, "tokenCounter", 0);
3778
- __publicField(this, "enableScoreSealing", false);
3779
- __publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
3780
- if (options?.enableScoreSealing) {
3781
- this.enableScoreSealing = true;
3782
- }
3783
- if (options?.scoreSealingSecret) {
3784
- this.scoreSealingSecret = options.scoreSealingSecret;
3670
+ __publicField(this, "sessionCounter", 0);
3671
+ __publicField(this, "requiresHash", false);
3672
+ if (options?.requiresHash) {
3673
+ this.requiresHash = true;
3785
3674
  }
3786
3675
  }
3787
- /**
3788
- * Configure mock leaderboard settings
3789
- *
3790
- * @param options - Configuration options
3791
- */
3792
3676
  configure(options) {
3793
- if (typeof options.enableScoreSealing === "boolean") {
3794
- this.enableScoreSealing = options.enableScoreSealing;
3795
- }
3796
- if (options.scoreSealingSecret) {
3797
- this.scoreSealingSecret = options.scoreSealingSecret;
3677
+ if (typeof options.requiresHash === "boolean") {
3678
+ this.requiresHash = options.requiresHash;
3798
3679
  }
3799
3680
  }
3800
3681
  generateNonce() {
@@ -3811,149 +3692,83 @@ var MockLeaderboardApi = class {
3811
3692
  }
3812
3693
  return this.entriesByMode.get(key);
3813
3694
  }
3814
- /**
3815
- * Create a mock score token for testing.
3816
- * Token is cached for automatic hash computation if score sealing is enabled.
3817
- *
3818
- * @param mode - Optional game mode
3819
- * @returns Score token with sealing data if enabled
3820
- */
3821
- async createScoreToken(mode) {
3822
- const token = `mock_token_${++this.tokenCounter}`;
3695
+ async startRun(mode) {
3696
+ const sessionId = `mock_session_${++this.sessionCounter}`;
3823
3697
  const startTime = Date.now();
3824
3698
  const expiresAt = startTime + 36e5;
3825
3699
  const resolvedMode = mode || "default";
3826
- const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
3827
- const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
3828
- this.tokens.set(token, {
3829
- id: token,
3700
+ const hashNonce = this.requiresHash ? this.generateNonce() : null;
3701
+ this.sessions.set(sessionId, {
3702
+ id: sessionId,
3830
3703
  expiresAt,
3831
3704
  mode: resolvedMode,
3832
- sealingNonce,
3705
+ hashNonce,
3833
3706
  used: false
3834
3707
  });
3835
- const result = {
3836
- token,
3708
+ return {
3709
+ sessionId,
3837
3710
  startTime,
3838
3711
  expiresAt,
3839
- sealingNonce,
3840
- sealingSecret,
3712
+ hashNonce,
3841
3713
  mode: resolvedMode
3842
3714
  };
3843
- this.tokenCache.set(token, result);
3844
- return result;
3845
3715
  }
3846
- /**
3847
- * Submit a mock score to the leaderboard.
3848
- * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3849
- *
3850
- * @param params - Score submission parameters
3851
- * @returns Submission result with acceptance status and rank
3852
- * @throws Error if token not found in cache or validation fails
3853
- */
3854
- async submitScore(params) {
3855
- let hash;
3856
- if (params.token) {
3857
- const cachedToken = this.tokenCache.get(params.token);
3858
- if (!cachedToken) {
3859
- throw new Error(
3860
- "Invalid token: not found in cache. Did you call createScoreToken() first?"
3861
- );
3862
- }
3863
- if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3864
- hash = await computeScoreHash(
3865
- params.score,
3866
- params.duration,
3867
- params.token,
3868
- cachedToken.sealingNonce,
3869
- cachedToken.sealingSecret
3870
- );
3871
- }
3872
- }
3873
- if (!params.token) {
3874
- const mode = params.mode || "default";
3875
- const submittedAt2 = Date.now();
3876
- const entry2 = {
3877
- profileId: `mock_profile`,
3878
- username: "Mock Player",
3879
- avatarUrl: null,
3880
- score: params.score,
3881
- duration: params.duration,
3882
- submittedAt: submittedAt2,
3883
- token: "simple-mode",
3884
- rank: null,
3885
- zScore: null,
3886
- isAnomaly: false,
3887
- trustScore: 50,
3888
- metadata: params.metadata ?? null,
3889
- isSeed: false
3890
- };
3891
- const modeEntries2 = this.getEntriesForMode(mode);
3892
- modeEntries2.push(entry2);
3893
- modeEntries2.sort((a, b) => {
3894
- if (b.score !== a.score) return b.score - a.score;
3895
- return a.submittedAt - b.submittedAt;
3896
- });
3897
- modeEntries2.forEach((e, index) => {
3898
- modeEntries2[index] = { ...e, rank: index + 1 };
3899
- });
3900
- const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
3901
- return {
3902
- accepted: true,
3903
- rank: inserted2?.rank ?? null
3904
- };
3905
- }
3906
- const scoreToken = this.tokens.get(params.token);
3907
- if (!scoreToken) {
3908
- throw new Error("Invalid score token");
3716
+ async submitScore(sessionId, score, durationSec, options) {
3717
+ const session = this.sessions.get(sessionId);
3718
+ if (!session) {
3719
+ throw new Error("Invalid leaderboard session");
3909
3720
  }
3910
- if (scoreToken.expiresAt < Date.now()) {
3911
- throw new Error("Invalid or expired score token");
3721
+ if (session.expiresAt < Date.now()) {
3722
+ throw new Error("Invalid or expired leaderboard session");
3912
3723
  }
3913
- if (scoreToken.used) {
3914
- throw new Error("Score token already used");
3724
+ if (session.used) {
3725
+ throw new Error("Leaderboard session already used");
3915
3726
  }
3916
- if (params.mode && params.mode !== scoreToken.mode) {
3917
- throw new Error("Submission mode does not match token mode");
3727
+ if (options?.mode && options.mode !== session.mode) {
3728
+ throw new Error("Submission mode does not match session mode");
3918
3729
  }
3919
- if (scoreToken.sealingNonce && !hash) {
3920
- throw new Error("Score hash required when score sealing is enabled");
3730
+ if (session.hashNonce && !options?.hash) {
3731
+ throw new Error("Score hash is required for sealed leaderboard submissions");
3921
3732
  }
3922
3733
  const submittedAt = Date.now();
3923
3734
  const entry = {
3924
3735
  profileId: `mock_profile`,
3925
3736
  username: "Mock Player",
3926
3737
  avatarUrl: null,
3927
- score: params.score,
3928
- duration: params.duration,
3738
+ score,
3739
+ durationSec,
3929
3740
  submittedAt,
3930
- token: params.token,
3741
+ sessionId,
3931
3742
  rank: null,
3932
3743
  zScore: null,
3933
3744
  isAnomaly: false,
3934
3745
  trustScore: 50,
3935
- metadata: params.metadata ?? null,
3746
+ metadata: options?.metadata ?? null,
3936
3747
  isSeed: false
3937
3748
  };
3938
- const modeEntries = this.getEntriesForMode(scoreToken.mode);
3749
+ const modeEntries = this.getEntriesForMode(session.mode);
3939
3750
  modeEntries.push(entry);
3940
3751
  modeEntries.sort((a, b) => {
3941
- if (b.score !== a.score) return b.score - a.score;
3752
+ if (b.score !== a.score) {
3753
+ return b.score - a.score;
3754
+ }
3942
3755
  return a.submittedAt - b.submittedAt;
3943
3756
  });
3944
3757
  modeEntries.forEach((e, index) => {
3945
- modeEntries[index] = { ...e, rank: index + 1 };
3758
+ modeEntries[index] = {
3759
+ ...e,
3760
+ rank: index + 1
3761
+ };
3946
3762
  });
3947
- scoreToken.used = true;
3948
- scoreToken.sealingNonce = null;
3949
- this.tokenCache.delete(params.token);
3950
- const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
3763
+ session.used = true;
3764
+ session.hashNonce = null;
3765
+ const inserted = modeEntries.find((e) => e.sessionId === sessionId && e.submittedAt === submittedAt);
3951
3766
  return {
3952
3767
  accepted: true,
3953
3768
  rank: inserted?.rank ?? null
3954
3769
  };
3955
3770
  }
3956
- async getPagedScores(options) {
3771
+ async getLeaderboard(options) {
3957
3772
  const limit = options?.limit ?? 10;
3958
3773
  const mode = options?.mode ?? "default";
3959
3774
  const modeEntries = [...this.getEntriesForMode(mode)];
@@ -3969,7 +3784,7 @@ var MockLeaderboardApi = class {
3969
3784
  periodInstance: options?.period ?? "alltime"
3970
3785
  };
3971
3786
  }
3972
- async getMyRank(_options) {
3787
+ async getPlayerStats(_options) {
3973
3788
  const mode = _options?.mode ?? "default";
3974
3789
  const modeEntries = this.getEntriesForMode(mode);
3975
3790
  const playerEntry = modeEntries[0] ?? null;
@@ -3982,7 +3797,7 @@ var MockLeaderboardApi = class {
3982
3797
  periodInstance: _options?.period ?? "alltime"
3983
3798
  };
3984
3799
  }
3985
- async getPodiumScores(options) {
3800
+ async getLeaderboardHighlight(options) {
3986
3801
  const mode = options?.mode ?? "default";
3987
3802
  const modeEntries = [...this.getEntriesForMode(mode)];
3988
3803
  const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
@@ -4055,23 +3870,112 @@ var RpcPreloaderApi = class {
4055
3870
  __publicField(this, "rpcClient");
4056
3871
  this.rpcClient = rpcClient;
4057
3872
  }
4058
- async showLoadScreen() {
4059
- await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
3873
+ async showLoadScreen() {
3874
+ await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
3875
+ }
3876
+ async hideLoadScreen() {
3877
+ await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
3878
+ }
3879
+ async setLoaderText(text) {
3880
+ await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
3881
+ }
3882
+ async setLoaderProgress(progress) {
3883
+ await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
3884
+ }
3885
+ };
3886
+
3887
+ // src/game-preloader/index.ts
3888
+ function initializePreloader(venusApi, host) {
3889
+ venusApi.preloader = host.preloader;
3890
+ }
3891
+
3892
+ // src/post/MockPostApi.ts
3893
+ var MockPostApi = class {
3894
+ constructor(venusApi) {
3895
+ __publicField(this, "venusApi");
3896
+ this.venusApi = venusApi;
3897
+ }
3898
+ async getPostInfo() {
3899
+ const venusApi = this.venusApi;
3900
+ await createMockDelay(MOCK_DELAYS.short);
3901
+ return venusApi._mock.currentPostInteractions;
3902
+ }
3903
+ async openCommentsAsync() {
3904
+ await createMockDelay(MOCK_DELAYS.short);
3905
+ return {
3906
+ opened: true,
3907
+ commentsCount: 0
3908
+ };
3909
+ }
3910
+ async toggleFollowAsync() {
3911
+ const venusApi = this.venusApi;
3912
+ console.log("[Venus Mock] *Toggling follow status");
3913
+ await createMockDelay(MOCK_DELAYS.short);
3914
+ venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
3915
+ const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
3916
+ return {
3917
+ isFollowing,
3918
+ action: isFollowing ? "followed" : "unfollowed"
3919
+ };
3920
+ }
3921
+ async toggleLikeAsync() {
3922
+ const venusApi = this.venusApi;
3923
+ await createMockDelay(MOCK_DELAYS.short);
3924
+ venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
3925
+ const isLiked = venusApi._mock.currentPostInteractions.isLiked;
3926
+ if (isLiked) {
3927
+ venusApi._mock.currentPostInteractions.likesCount++;
3928
+ } else {
3929
+ venusApi._mock.currentPostInteractions.likesCount = Math.max(
3930
+ 0,
3931
+ venusApi._mock.currentPostInteractions.likesCount - 1
3932
+ );
3933
+ }
3934
+ return {
3935
+ isLiked,
3936
+ likesCount: venusApi._mock.currentPostInteractions.likesCount,
3937
+ action: isLiked ? "liked" : "unliked"
3938
+ };
3939
+ }
3940
+ };
3941
+
3942
+ // src/post/RpcPostApi.ts
3943
+ var RpcPostApi = class {
3944
+ constructor(rpcClient) {
3945
+ __publicField(this, "rpcClient");
3946
+ this.rpcClient = rpcClient;
3947
+ }
3948
+ getPostInfo() {
3949
+ return this.rpcClient.call("H5_GET_POST_INTERACTIONS" /* GET_POST_INTERACTIONS */, {});
4060
3950
  }
4061
- async hideLoadScreen() {
4062
- await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
3951
+ openCommentsAsync() {
3952
+ return this.rpcClient.call("H5_OPEN_COMMENTS" /* OPEN_COMMENTS */, {});
4063
3953
  }
4064
- async setLoaderText(text) {
4065
- await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
3954
+ toggleFollowAsync() {
3955
+ return this.rpcClient.call(
3956
+ "H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
3957
+ {}
3958
+ );
4066
3959
  }
4067
- async setLoaderProgress(progress) {
4068
- await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
3960
+ toggleLikeAsync() {
3961
+ return this.rpcClient.call("H5_TOGGLE_LIKE" /* TOGGLE_LIKE */, {});
4069
3962
  }
4070
3963
  };
4071
3964
 
4072
- // src/game-preloader/index.ts
4073
- function initializePreloader(venusApi, host) {
4074
- venusApi.preloader = host.preloader;
3965
+ // src/post/index.ts
3966
+ function initializePost(venusApi, host) {
3967
+ venusApi.getPostInteractionsAsync = () => {
3968
+ return host.post.getPostInfo();
3969
+ };
3970
+ venusApi.toggleFollowAsync = () => {
3971
+ return host.post.toggleFollowAsync();
3972
+ };
3973
+ venusApi.toggleLikeAsync = () => {
3974
+ return host.post.toggleLikeAsync();
3975
+ };
3976
+ venusApi.openCommentsAsync = async () => {
3977
+ await host.post.openCommentsAsync();
3978
+ };
4075
3979
  }
4076
3980
 
4077
3981
  // src/social/MockSocialApi.ts
@@ -4176,16 +4080,6 @@ var VenusTransport = class {
4176
4080
  this.isProcessingMessage = false;
4177
4081
  return;
4178
4082
  }
4179
- if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
4180
- const notification = {
4181
- type: "rpc-notification",
4182
- id: message.type,
4183
- payload: message.data
4184
- };
4185
- this.handleNotification(notification);
4186
- this.isProcessingMessage = false;
4187
- return;
4188
- }
4189
4083
  const requestId = messageData.requestId;
4190
4084
  if (!requestId) {
4191
4085
  this.logWarn("No requestId. Ignoring message...");
@@ -4352,6 +4246,294 @@ var VenusTransport = class {
4352
4246
  }
4353
4247
  };
4354
4248
 
4249
+ // src/RemoteHost.ts
4250
+ init_rooms();
4251
+
4252
+ // src/rooms/RpcRoomsApi.ts
4253
+ init_VenusRoom();
4254
+ var RpcRoomsApi = class {
4255
+ constructor(rpcClient) {
4256
+ __publicField(this, "rpcClient");
4257
+ __publicField(this, "subscriptions");
4258
+ __publicField(this, "transportSubscription", null);
4259
+ this.rpcClient = rpcClient;
4260
+ this.subscriptions = {
4261
+ data: {},
4262
+ messages: {},
4263
+ gameEvents: {},
4264
+ allEvents: {}
4265
+ };
4266
+ }
4267
+ /**
4268
+ * Get the subscription state for external access (used by setupRoomNotifications)
4269
+ */
4270
+ getSubscriptions() {
4271
+ return this.subscriptions;
4272
+ }
4273
+ /**
4274
+ * Set up room notification routing from the transport
4275
+ */
4276
+ setupNotifications(transport) {
4277
+ const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
4278
+ this.transportSubscription = setupRoomNotifications2(
4279
+ transport,
4280
+ () => this.getSubscriptions()
4281
+ );
4282
+ }
4283
+ /**
4284
+ * Clean up subscriptions and resources
4285
+ */
4286
+ dispose() {
4287
+ if (this.transportSubscription) {
4288
+ this.transportSubscription.unsubscribe();
4289
+ this.transportSubscription = null;
4290
+ console.log("[Venus Rooms] Cleaned up room notification subscription");
4291
+ }
4292
+ }
4293
+ async createRoom(options) {
4294
+ const response = await this.rpcClient.call(
4295
+ "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
4296
+ {
4297
+ options
4298
+ }
4299
+ );
4300
+ if (response.success === false) {
4301
+ throw new Error(response.error || "Failed to create room");
4302
+ }
4303
+ const roomData = response.roomData || response;
4304
+ const room = new VenusRoom(roomData);
4305
+ return room;
4306
+ }
4307
+ async joinOrCreateRoom(options) {
4308
+ const response = await this.rpcClient.call(
4309
+ "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
4310
+ {
4311
+ options
4312
+ }
4313
+ );
4314
+ if (response.success === false) {
4315
+ throw new Error(response.error || "Failed to join or create room");
4316
+ }
4317
+ const data = response.value || response;
4318
+ const room = new VenusRoom(data.roomData);
4319
+ return {
4320
+ action: data.action,
4321
+ room,
4322
+ playersJoined: data.playersJoined
4323
+ };
4324
+ }
4325
+ async joinRoomByCode(roomCode) {
4326
+ const response = await this.rpcClient.call(
4327
+ "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
4328
+ {
4329
+ roomCode
4330
+ }
4331
+ );
4332
+ if (response?.success === false) {
4333
+ throw new Error(response.error || "Failed to join room by code");
4334
+ }
4335
+ const roomData = response.roomData || response;
4336
+ const room = new VenusRoom(roomData);
4337
+ return room;
4338
+ }
4339
+ // Get user's rooms with optional filtering
4340
+ async getUserRooms(includeArchived = false) {
4341
+ const response = await this.rpcClient.call(
4342
+ "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
4343
+ {
4344
+ includeArchived
4345
+ }
4346
+ );
4347
+ if (response?.success === false) {
4348
+ throw new Error(response.error || "Failed to get user rooms");
4349
+ }
4350
+ const rawRooms = response.rooms || [];
4351
+ const venusRooms = [];
4352
+ for (const roomData of rawRooms) {
4353
+ if (!roomData.id) {
4354
+ console.warn("getUserRooms: Skipping room with missing ID:", roomData);
4355
+ continue;
4356
+ }
4357
+ try {
4358
+ const venusRoom = new VenusRoom(roomData);
4359
+ venusRooms.push(venusRoom);
4360
+ } catch (error) {
4361
+ console.warn(
4362
+ "getUserRooms: Failed to create VenusRoom object:",
4363
+ error,
4364
+ roomData
4365
+ );
4366
+ }
4367
+ }
4368
+ return venusRooms;
4369
+ }
4370
+ async updateData(room, updates, merge = true) {
4371
+ const response = await this.rpcClient.call(
4372
+ "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
4373
+ {
4374
+ roomId: room.id,
4375
+ updates,
4376
+ merge
4377
+ }
4378
+ );
4379
+ if (response?.success === false) {
4380
+ throw new Error(response.error || "Failed to update room data");
4381
+ }
4382
+ return response.data;
4383
+ }
4384
+ async getData(room) {
4385
+ const response = await this.rpcClient.call(
4386
+ "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
4387
+ {
4388
+ roomId: room.id
4389
+ }
4390
+ );
4391
+ if (response?.success === false) {
4392
+ throw new Error(response.error || "Failed to get room data");
4393
+ }
4394
+ return response.data;
4395
+ }
4396
+ async sendMessage(venusRoom, messageData) {
4397
+ const response = await this.rpcClient.call(
4398
+ "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
4399
+ {
4400
+ roomId: venusRoom.id,
4401
+ message: messageData
4402
+ }
4403
+ );
4404
+ if (response?.success === false) {
4405
+ throw new Error(response.error || "Failed to send message");
4406
+ }
4407
+ return response.messageId;
4408
+ }
4409
+ async leave(room) {
4410
+ const response = await this.rpcClient.call(
4411
+ "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
4412
+ {
4413
+ roomId: room.id
4414
+ }
4415
+ );
4416
+ if (response?.success === false) {
4417
+ throw new Error(response.error || "Failed to leave room");
4418
+ }
4419
+ return response;
4420
+ }
4421
+ async startGame(room, gameConfig = {}, turnOrder = null) {
4422
+ const response = await this.rpcClient.call(
4423
+ "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
4424
+ {
4425
+ roomId: room.id,
4426
+ gameConfig,
4427
+ turnOrder
4428
+ }
4429
+ );
4430
+ if (response?.success === false) {
4431
+ throw new Error(response.error || "Failed to start game");
4432
+ }
4433
+ return response.data;
4434
+ }
4435
+ async proposeMove(room, proposalPayload) {
4436
+ const response = await this.rpcClient.call(
4437
+ "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
4438
+ {
4439
+ roomId: room.id,
4440
+ gameSpecificState: proposalPayload.gameSpecificState,
4441
+ moveType: proposalPayload.moveType,
4442
+ clientContext: proposalPayload.clientContext,
4443
+ clientProposalId: proposalPayload.clientProposalId
4444
+ }
4445
+ );
4446
+ if (response?.success === false) {
4447
+ throw new Error(response.error || "Failed to propose move");
4448
+ }
4449
+ return response.data;
4450
+ }
4451
+ async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
4452
+ console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
4453
+ return { success: true, moveId, isValid, reason };
4454
+ }
4455
+ async roomSubscribeToGameEvents(room, callback) {
4456
+ "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
4457
+ if (!this.subscriptions.gameEvents[room.id]) {
4458
+ this.subscriptions.gameEvents[room.id] = [];
4459
+ }
4460
+ this.subscriptions.gameEvents[room.id].push(callback);
4461
+ }
4462
+ subscribe(room, options = {}) {
4463
+ const subscriptionIds = [];
4464
+ const roomId = room.id;
4465
+ if (options.onData) {
4466
+ const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
4467
+ if (!this.subscriptions.data[roomId]) {
4468
+ this.subscriptions.data[roomId] = [];
4469
+ }
4470
+ this.subscriptions.data[roomId].push(options.onData);
4471
+ subscriptionIds.push({
4472
+ type: "data",
4473
+ id: dataSubId,
4474
+ callback: options.onData
4475
+ });
4476
+ }
4477
+ if (options.onMessages) {
4478
+ const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
4479
+ if (!this.subscriptions.messages[roomId]) {
4480
+ this.subscriptions.messages[roomId] = [];
4481
+ }
4482
+ this.subscriptions.messages[roomId].push(options.onMessages);
4483
+ subscriptionIds.push({
4484
+ type: "messages",
4485
+ id: msgSubId,
4486
+ callback: options.onMessages
4487
+ });
4488
+ }
4489
+ if (options.onMoves || options.onGameEvents) {
4490
+ const handler = options.onMoves || options.onGameEvents;
4491
+ if (handler) {
4492
+ const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
4493
+ if (!this.subscriptions.gameEvents[roomId]) {
4494
+ this.subscriptions.gameEvents[roomId] = [];
4495
+ }
4496
+ this.subscriptions.gameEvents[roomId].push(handler);
4497
+ subscriptionIds.push({
4498
+ type: "gameEvents",
4499
+ id: gameSubId,
4500
+ callback: handler
4501
+ });
4502
+ }
4503
+ }
4504
+ 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;
4505
+ if (needsSubscription) {
4506
+ this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
4507
+ roomId,
4508
+ subscribeToData: !!options.onData,
4509
+ subscribeToMessages: !!options.onMessages,
4510
+ subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
4511
+ }).catch((error) => {
4512
+ console.error("Failed to set up room subscription:", error);
4513
+ });
4514
+ }
4515
+ let called = false;
4516
+ return () => {
4517
+ if (called) return;
4518
+ called = true;
4519
+ subscriptionIds.forEach((sub) => {
4520
+ const bucket = this.subscriptions[sub.type];
4521
+ const callbacks = bucket && bucket[roomId] || [];
4522
+ const index = callbacks.indexOf(sub.callback);
4523
+ if (index > -1) callbacks.splice(index, 1);
4524
+ });
4525
+ const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
4526
+ if (hasNoCallbacks) {
4527
+ this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
4528
+ roomId
4529
+ }).catch((error) => {
4530
+ console.error("Failed to clean up room subscription:", error);
4531
+ });
4532
+ }
4533
+ };
4534
+ }
4535
+ };
4536
+
4355
4537
  // src/RemoteHost.ts
4356
4538
  var getCdnBaseUrl = () => {
4357
4539
  return "https://venus-static-01293ak.web.app/";
@@ -4368,9 +4550,9 @@ var RemoteHost = class {
4368
4550
  __publicField(this, "notifications");
4369
4551
  __publicField(this, "popups");
4370
4552
  __publicField(this, "profile");
4371
- __publicField(this, "system");
4372
4553
  __publicField(this, "cdn");
4373
4554
  __publicField(this, "time");
4555
+ __publicField(this, "post");
4374
4556
  __publicField(this, "ai");
4375
4557
  __publicField(this, "haptics");
4376
4558
  __publicField(this, "features");
@@ -4424,12 +4606,10 @@ var RemoteHost = class {
4424
4606
  this.navigation = new RpcNavigationApi(rpcClient, venusApi);
4425
4607
  this.notifications = new RpcNotificationsApi(rpcClient);
4426
4608
  this.popups = new RpcPopupsApi(rpcClient);
4427
- this.profile = new HostProfileApi(venusApi);
4428
- const deviceApi = new HostDeviceApi(venusApi);
4429
- const environmentApi = new HostEnvironmentApi(venusApi);
4430
- this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
4609
+ this.profile = new HostProfileApi();
4431
4610
  this.cdn = new HostCdnApi(getCdnBaseUrl());
4432
- this.time = new HostTimeApi(rpcClient, venusApi);
4611
+ this.time = new HostTimeApi(rpcClient);
4612
+ this.post = new RpcPostApi(rpcClient);
4433
4613
  this.ai = new RpcAiApi(rpcClient);
4434
4614
  this.haptics = new RpcHapticsApi(rpcClient);
4435
4615
  this.features = new RpcFeaturesApi(rpcClient);
@@ -4444,6 +4624,7 @@ var RemoteHost = class {
4444
4624
  venusApi.isMock = () => false;
4445
4625
  this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
4446
4626
  initializeRoomsApi(this.venusApi, this);
4627
+ console.log("[Venus SDK] Remote host created");
4447
4628
  }
4448
4629
  get isInitialized() {
4449
4630
  return this._isInitialized;
@@ -4462,27 +4643,35 @@ var RemoteHost = class {
4462
4643
  );
4463
4644
  transport.instanceId = response.instanceId;
4464
4645
  this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
4465
- const profile = response.profile;
4466
- const sanitizedProfile = {
4467
- id: profile.id,
4468
- username: profile.username,
4469
- avatarUrl: profile.avatarUrl ?? null,
4470
- isAnonymous: Boolean(profile.isAnonymous)
4471
- };
4472
- this.venusApi._profileData = sanitizedProfile;
4473
- this.venusApi._deviceData = response.device;
4474
- this.venusApi._environmentData = response.environment;
4475
- this.venusApi._localeData = response.locale;
4476
- this.venusApi._languageCodeData = response.languageCode;
4646
+ if (response.profile) {
4647
+ const profile = response.profile;
4648
+ const sanitizedProfile = {
4649
+ id: profile.id,
4650
+ username: profile.username,
4651
+ avatarUrl: profile.avatarUrl ?? null,
4652
+ isAnonymous: Boolean(profile.isAnonymous)
4653
+ };
4654
+ if (typeof window !== "undefined") {
4655
+ const globalWindow = window;
4656
+ const venus = globalWindow.venus || (globalWindow.venus = {});
4657
+ venus.profile = sanitizedProfile;
4658
+ if (venus._config) {
4659
+ venus._config.profile = sanitizedProfile;
4660
+ }
4661
+ if (venus.config) {
4662
+ venus.config.profile = sanitizedProfile;
4663
+ }
4664
+ }
4665
+ }
4477
4666
  this._isInitialized = true;
4478
- this.venusApi.launchParams = response.launchParams;
4667
+ this.venusApi.launchParams = response.launchParams || {};
4479
4668
  await this.rpcClient.call("READY" /* READY */, {});
4480
- const safeArea = response.safeArea;
4481
- if (safeArea) {
4482
- this.venusApi._safeAreaData = safeArea;
4669
+ const hudInsets = response.hudInsets;
4670
+ if (hudInsets) {
4671
+ this.venusApi.config.ui.safeArea = hudInsets;
4483
4672
  }
4484
4673
  return {
4485
- safeArea,
4674
+ hudInsets,
4486
4675
  initializeAsleep: response.initializeAsleep
4487
4676
  };
4488
4677
  }
@@ -4492,120 +4681,49 @@ var RemoteHost = class {
4492
4681
  };
4493
4682
 
4494
4683
  // src/MockHost.ts
4684
+ init_rooms();
4495
4685
  var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when running inside the Venus host environment.";
4496
4686
  function createUnavailableRoomsApi() {
4497
4687
  const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
4498
4688
  return {
4499
- async createRoomAsync() {
4689
+ async createRoom() {
4500
4690
  throw roomsUnavailableError();
4501
4691
  },
4502
- async joinOrCreateRoomAsync() {
4692
+ async joinOrCreateRoom() {
4503
4693
  throw roomsUnavailableError();
4504
4694
  },
4505
- async joinRoomByCodeAsync() {
4695
+ async getUserRooms() {
4506
4696
  throw roomsUnavailableError();
4507
4697
  },
4508
- async getUserRoomsAsync() {
4698
+ async joinRoomByCode() {
4509
4699
  throw roomsUnavailableError();
4510
4700
  },
4511
- async subscribeAsync() {
4701
+ subscribe() {
4512
4702
  throw roomsUnavailableError();
4513
4703
  },
4514
- async updateRoomDataAsync() {
4704
+ async updateData() {
4515
4705
  throw roomsUnavailableError();
4516
4706
  },
4517
- async getRoomDataAsync() {
4707
+ async getData() {
4518
4708
  throw roomsUnavailableError();
4519
4709
  },
4520
- async sendRoomMessageAsync() {
4710
+ async sendMessage() {
4521
4711
  throw roomsUnavailableError();
4522
4712
  },
4523
- async leaveRoomAsync() {
4713
+ async leave() {
4524
4714
  throw roomsUnavailableError();
4525
4715
  },
4526
- async startRoomGameAsync() {
4716
+ async startGame() {
4527
4717
  throw roomsUnavailableError();
4528
4718
  },
4529
- async proposeMoveAsync() {
4719
+ async proposeMove() {
4530
4720
  throw roomsUnavailableError();
4531
4721
  },
4532
- async validateMoveAsync() {
4722
+ async validateMove() {
4533
4723
  throw roomsUnavailableError();
4534
4724
  }
4535
4725
  };
4536
4726
  }
4537
- var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
4538
- function createUnavailableSimulationApi() {
4539
- const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
4540
- return {
4541
- isEnabled() {
4542
- return false;
4543
- },
4544
- async getStateAsync() {
4545
- throw simulationUnavailableError();
4546
- },
4547
- async getConfigAsync() {
4548
- throw simulationUnavailableError();
4549
- },
4550
- async executeRecipeAsync() {
4551
- throw simulationUnavailableError();
4552
- },
4553
- async getActiveRunsAsync() {
4554
- throw simulationUnavailableError();
4555
- },
4556
- async collectRecipeAsync() {
4557
- throw simulationUnavailableError();
4558
- },
4559
- async executeScopedRecipeAsync() {
4560
- throw simulationUnavailableError();
4561
- },
4562
- async triggerRecipeChainAsync() {
4563
- throw simulationUnavailableError();
4564
- },
4565
- async getAvailableRecipesAsync() {
4566
- throw simulationUnavailableError();
4567
- },
4568
- async getRecipeRequirementsAsync() {
4569
- throw simulationUnavailableError();
4570
- },
4571
- async getBatchRecipeRequirementsAsync() {
4572
- throw simulationUnavailableError();
4573
- },
4574
- async resolveFieldValueAsync() {
4575
- throw simulationUnavailableError();
4576
- },
4577
- async getEntityMetadataAsync() {
4578
- throw simulationUnavailableError();
4579
- },
4580
- async getSlotContainersAsync() {
4581
- throw simulationUnavailableError();
4582
- },
4583
- async getSlotAssignmentsAsync() {
4584
- throw simulationUnavailableError();
4585
- },
4586
- async assignItemToSlotAsync() {
4587
- throw simulationUnavailableError();
4588
- },
4589
- async removeItemFromSlotAsync() {
4590
- throw simulationUnavailableError();
4591
- },
4592
- async getAvailableItemsAsync() {
4593
- throw simulationUnavailableError();
4594
- },
4595
- async calculatePowerPreviewAsync() {
4596
- throw simulationUnavailableError();
4597
- },
4598
- async validateSlotAssignmentAsync() {
4599
- throw simulationUnavailableError();
4600
- },
4601
- async executeBatchOperationsAsync() {
4602
- throw simulationUnavailableError();
4603
- },
4604
- async subscribeAsync() {
4605
- throw simulationUnavailableError();
4606
- }
4607
- };
4608
- }
4609
4727
  var MockHost = class {
4610
4728
  constructor(venusApi) {
4611
4729
  __publicField(this, "ads");
@@ -4618,9 +4736,9 @@ var MockHost = class {
4618
4736
  __publicField(this, "notifications");
4619
4737
  __publicField(this, "popups");
4620
4738
  __publicField(this, "profile");
4621
- __publicField(this, "system");
4622
4739
  __publicField(this, "cdn");
4623
4740
  __publicField(this, "time");
4741
+ __publicField(this, "post");
4624
4742
  __publicField(this, "ai");
4625
4743
  __publicField(this, "haptics");
4626
4744
  __publicField(this, "features");
@@ -4652,17 +4770,15 @@ var MockHost = class {
4652
4770
  this.navigation = new MockNavigationApi(venusApi);
4653
4771
  this.notifications = new MockNotificationsApi(venusApi);
4654
4772
  this.popups = new MockPopupsApi(this._overlay);
4655
- this.profile = new MockProfileApi(venusApi);
4656
- const deviceApi = new MockDeviceApi(venusApi);
4657
- const environmentApi = new MockEnvironmentApi(venusApi);
4658
- this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
4659
- this.cdn = new MockCdnApi(venusApi);
4773
+ this.profile = new MockProfileApi();
4774
+ this.cdn = new MockCdnApi();
4660
4775
  this.time = new MockTimeApi(venusApi);
4776
+ this.post = new MockPostApi(venusApi);
4661
4777
  this.ai = new MockAiApi();
4662
4778
  this.haptics = new MockHapticsApi(venusApi);
4663
4779
  this.features = new MockFeaturesApi();
4664
4780
  this.lifecycle = this._mockLifecyclesApi;
4665
- this.simulation = createUnavailableSimulationApi();
4781
+ this.simulation = new MockSimulationApi();
4666
4782
  this.rooms = createUnavailableRoomsApi();
4667
4783
  this.logging = new MockLoggingApi();
4668
4784
  this.iap = new MockIapApi();
@@ -4678,17 +4794,40 @@ var MockHost = class {
4678
4794
  }
4679
4795
  initialize(options) {
4680
4796
  this._isInitialized = true;
4681
- this.venusApi._profileData = this.profile.getCurrentProfile();
4682
- this.venusApi._deviceData = this.system.getDevice();
4683
- this.venusApi._environmentData = this.system.getEnvironment();
4684
- this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
4685
- this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
4797
+ const controls = this.updateUiControls();
4686
4798
  return Promise.resolve({
4687
4799
  initializeAsleep: false,
4688
- safeArea: this.venusApi._safeAreaData
4800
+ hudInsets: {
4801
+ top: controls.feedHeader.height,
4802
+ bottom: 0,
4803
+ left: 0,
4804
+ right: 0
4805
+ }
4689
4806
  });
4690
4807
  }
4808
+ updateUiControls() {
4809
+ const controls = {
4810
+ closeButton: { x: 16, y: 16, width: 32, height: 32 },
4811
+ menuButton: {
4812
+ x: window.innerWidth - 48,
4813
+ y: 16,
4814
+ width: 32,
4815
+ height: 32
4816
+ },
4817
+ feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
4818
+ playButton: {
4819
+ x: 0,
4820
+ y: window.innerHeight - 60,
4821
+ width: window.innerWidth,
4822
+ height: 60
4823
+ }
4824
+ };
4825
+ return controls;
4826
+ }
4691
4827
  createOverlay() {
4828
+ const venusApi = this.venusApi;
4829
+ venusApi.config.ui.controls = this.updateUiControls();
4830
+ const uiControls = venusApi.config.ui.controls;
4692
4831
  const overlayContainer = document.createElement("div");
4693
4832
  overlayContainer.id = "venus-mock-overlay";
4694
4833
  overlayContainer.style.cssText = `
@@ -4704,7 +4843,7 @@ var MockHost = class {
4704
4843
  const menuButton = this.createOverlayButton(
4705
4844
  "close",
4706
4845
  "Menu",
4707
- { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
4846
+ uiControls.menuButton,
4708
4847
  () => {
4709
4848
  this.handleMenuButtonClicked();
4710
4849
  },
@@ -4933,13 +5072,17 @@ var MockHost = class {
4933
5072
  return button;
4934
5073
  }
4935
5074
  updateOverlayLayout() {
5075
+ const venusApi = this.venusApi;
4936
5076
  const overlay = this._overlay;
5077
+ venusApi.config.ui.controls = this.updateUiControls();
5078
+ const uiControls = venusApi.config.ui.controls;
4937
5079
  const menuBtn = overlay.elements.menuButton;
4938
- menuBtn.style.left = `${window.innerWidth - 48}px`;
4939
- menuBtn.style.top = "16px";
4940
- menuBtn.style.width = "32px";
4941
- menuBtn.style.minWidth = "32px";
4942
- menuBtn.style.height = "32px";
5080
+ const menuPos = uiControls.menuButton;
5081
+ menuBtn.style.left = `${menuPos.x}px`;
5082
+ menuBtn.style.top = `${menuPos.y}px`;
5083
+ menuBtn.style.width = `${menuPos.width}px`;
5084
+ menuBtn.style.minWidth = `${menuPos.width}px`;
5085
+ menuBtn.style.height = `${menuPos.height}px`;
4943
5086
  }
4944
5087
  triggerLifecycleEvent(name) {
4945
5088
  console.log("Trigger Lifecycle Event: ", name);
@@ -5130,8 +5273,10 @@ var MockHost = class {
5130
5273
  // src/Host.ts
5131
5274
  function createHost(venusApi, isMock) {
5132
5275
  if (isMock) {
5276
+ console.log("[Venus SDK] Creating Local Host");
5133
5277
  return new MockHost(venusApi);
5134
5278
  } else {
5279
+ console.log("[Venus SDK] Creating Remote Host");
5135
5280
  return new RemoteHost(venusApi);
5136
5281
  }
5137
5282
  }
@@ -5144,6 +5289,6 @@ function initializeSocial(venusApi, host) {
5144
5289
  };
5145
5290
  }
5146
5291
 
5147
- export { DEFAULT_SHARED_LIB_CDN_BASE, EMBEDDED_LIBRARIES, EMBEDDED_LIBRARY_BY_KEY, HASH_ALGORITHM_NODE, HASH_ALGORITHM_WEB_CRYPTO, HapticFeedbackStyle, HostCdnApi, HostDeviceApi, HostEnvironmentApi, HostProfileApi, HostSystemApi, HostTimeApi, MODULE_TO_LIBRARY_SPECIFIERS, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockDeviceApi, MockEnvironmentApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLeaderboardApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockPreloaderApi, MockProfileApi, MockSharedAssetsApi, MockSocialApi, MockStorageApi, MockSystemApi, MockTimeApi, RemoteHost, RpcAdsApi, RpcAiApi, RpcAnalyticsApi, RpcAvatarApi, RpcClient, RpcFeaturesApi, RpcHapticsApi, RpcIapApi, RpcLeaderboardApi, RpcLifecycleApi, RpcLoggingApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, RpcPreloaderApi, RpcRoomsApi, RpcSharedAssetsApi, RpcSimulationApi, RpcSocialApi, RpcStorageApi, SDK_VERSION, VenusMessageId, VenusRoom, base64ToArrayBuffer, base64ToUtf8, computeScoreHash, createHost, createMockStorageApi, getLibraryDefinition, initializeAds, initializeAi, initializeAnalytics, initializeAvatar3d, initializeCdn, initializeFeaturesApi, initializeHaptics, initializeIap, initializeLeaderboard, initializeLifecycleApi, initializeLocalNotifications, initializeLoggingApi, initializePopups, initializePreloader, initializeProfile, initializeRoomsApi, initializeSimulation, initializeSocial, initializeStackNavigation, initializeStorage, initializeSystem, initializeTime, isPacificDaylightTime, setupRoomNotifications };
5148
- //# sourceMappingURL=chunk-U6NFOU3E.mjs.map
5149
- //# sourceMappingURL=chunk-U6NFOU3E.mjs.map
5292
+ export { HapticFeedbackStyle, HostCdnApi, HostProfileApi, HostTimeApi, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLeaderboardApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockPreloaderApi, MockProfileApi, MockSharedAssetsApi, MockSimulationApi, MockSocialApi, MockStorageApi, MockTimeApi, RemoteHost, RpcAdsApi, RpcAiApi, RpcAnalyticsApi, RpcAvatarApi, RpcClient, RpcFeaturesApi, RpcHapticsApi, RpcIapApi, RpcLeaderboardApi, RpcLifecycleApi, RpcLoggingApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, RpcPreloaderApi, RpcSharedAssetsApi, RpcSimulationApi, RpcSocialApi, RpcStorageApi, SDK_VERSION, VenusMessageId, VenusRoom, createHost, createMockStorageApi, init_rooms, initializeAds, initializeAi, initializeAnalytics, initializeAvatar3d, initializeCdn, initializeFeaturesApi, initializeHaptics, initializeIap, initializeLeaderboard, initializeLifecycleApi, initializeLocalNotifications, initializeLoggingApi, initializePopups, initializePost, initializePreloader, initializeProfile, initializeRoomsApi, initializeSimulation, initializeSocial, initializeStackNavigation, initializeStorage, initializeTime, isPacificDaylightTime, setupRoomNotifications };
5293
+ //# sourceMappingURL=chunk-PXWCNWJ6.mjs.map
5294
+ //# sourceMappingURL=chunk-PXWCNWJ6.mjs.map