@series-inc/venus-sdk 3.1.1-beta.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{AdsApi-meVfUcZy.d.mts → AdsApi-BV_VKgMO.d.mts} +467 -269
  2. package/dist/{AdsApi-meVfUcZy.d.ts → AdsApi-BV_VKgMO.d.ts} +467 -269
  3. package/dist/{chunk-EMVTVSGL.mjs → chunk-FTIFUYDL.mjs} +978 -1412
  4. package/dist/chunk-FTIFUYDL.mjs.map +1 -0
  5. package/dist/chunk-NSSMTXJJ.mjs +7 -0
  6. package/dist/{chunk-2PDL7CQK.mjs.map → chunk-NSSMTXJJ.mjs.map} +1 -1
  7. package/dist/chunk-UXY5CKKG.mjs +12 -0
  8. package/dist/chunk-UXY5CKKG.mjs.map +1 -0
  9. package/dist/{core-5JLON75E.mjs → core-62LWDHN7.mjs} +3 -3
  10. package/dist/{core-5JLON75E.mjs.map → core-62LWDHN7.mjs.map} +1 -1
  11. package/dist/index.cjs +1018 -1783
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.mts +142 -68
  14. package/dist/index.d.ts +142 -68
  15. package/dist/index.mjs +3 -7
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/venus-api/index.cjs +1091 -1883
  18. package/dist/venus-api/index.cjs.map +1 -1
  19. package/dist/venus-api/index.d.mts +2 -2
  20. package/dist/venus-api/index.d.ts +2 -2
  21. package/dist/venus-api/index.mjs +76 -418
  22. package/dist/venus-api/index.mjs.map +1 -1
  23. package/dist/vite/index.cjs.map +1 -1
  24. package/dist/vite/index.mjs.map +1 -1
  25. package/dist/webview/index.cjs +4 -335
  26. package/dist/webview/index.cjs.map +1 -1
  27. package/dist/webview/index.d.mts +7 -9
  28. package/dist/webview/index.d.ts +7 -9
  29. package/dist/webview/index.mjs +2 -2
  30. package/package.json +1 -1
  31. package/dist/chunk-2PDL7CQK.mjs +0 -26
  32. package/dist/chunk-EMVTVSGL.mjs.map +0 -1
  33. package/dist/chunk-IZLOB7DV.mjs +0 -343
  34. package/dist/chunk-IZLOB7DV.mjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,243 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
4
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
- };
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
14
- };
15
- var __copyProps = (to, from, except, desc) => {
16
- if (from && typeof from === "object" || typeof from === "function") {
17
- for (let key of __getOwnPropNames(from))
18
- if (!__hasOwnProp.call(to, key) && key !== except)
19
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
- }
21
- return to;
22
- };
23
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
5
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
25
6
 
26
- // src/rooms/RoomsApi.ts
27
- var init_RoomsApi = __esm({
28
- "src/rooms/RoomsApi.ts"() {
29
- }
30
- });
31
-
32
- // src/rooms/VenusRoom.ts
33
- exports.VenusRoom = void 0;
34
- var init_VenusRoom = __esm({
35
- "src/rooms/VenusRoom.ts"() {
36
- exports.VenusRoom = class {
37
- constructor(roomData) {
38
- __publicField(this, "id");
39
- __publicField(this, "name");
40
- __publicField(this, "players");
41
- __publicField(this, "maxPlayers");
42
- __publicField(this, "gameType");
43
- __publicField(this, "appId");
44
- __publicField(this, "type");
45
- __publicField(this, "createdBy");
46
- __publicField(this, "createdAt");
47
- __publicField(this, "updatedAt");
48
- __publicField(this, "isPrivate");
49
- __publicField(this, "currentPlayers");
50
- __publicField(this, "status");
51
- __publicField(this, "customMetadata");
52
- __publicField(this, "admins");
53
- __publicField(this, "roomCode");
54
- __publicField(this, "description");
55
- __publicField(this, "data");
56
- __publicField(this, "version");
57
- __publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
58
- this.id = roomData.id;
59
- this.name = roomData.name;
60
- this.players = roomData.currentPlayers || [];
61
- this.maxPlayers = roomData.maxPlayers;
62
- this.gameType = roomData.gameType;
63
- this.appId = roomData.appId;
64
- this.type = roomData.type;
65
- this.createdBy = roomData.createdBy;
66
- this.createdAt = roomData.createdAt;
67
- this.updatedAt = roomData.updatedAt;
68
- this.isPrivate = roomData.isPrivate;
69
- this.currentPlayers = roomData.currentPlayers || [];
70
- this.status = roomData.status;
71
- this.customMetadata = roomData.customMetadata || {};
72
- this.admins = roomData.admins || [];
73
- this.roomCode = roomData.roomCode;
74
- this.description = roomData.description;
75
- this.data = roomData.data || {};
76
- this.version = roomData.version;
77
- console.log(`VenusRoom: Created room object for ${this.id}`, {
78
- hasCustomMetadata: !!this.customMetadata,
79
- hasGameState: !!this.customMetadata?.rules?.gameState,
80
- gamePhase: this.customMetadata?.rules?.gameState?.phase,
81
- currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
82
- });
83
- }
84
- updateFromRoomData(newRoomData) {
85
- if (newRoomData.id === this.id) {
86
- this.name = newRoomData.name || this.name;
87
- this.players = newRoomData.currentPlayers || this.players;
88
- this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
89
- this.gameType = newRoomData.gameType || this.gameType;
90
- this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
91
- this.customMetadata = newRoomData.customMetadata || this.customMetadata;
92
- this.data = newRoomData.data || this.data;
93
- this.status = newRoomData.status || this.status;
94
- this.updatedAt = newRoomData.updatedAt || this.updatedAt;
95
- console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
96
- hasCustomMetadata: !!this.customMetadata,
97
- hasGameState: !!this.customMetadata?.rules?.gameState,
98
- gamePhase: this.customMetadata?.rules?.gameState?.phase,
99
- currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
100
- });
101
- }
102
- }
103
- };
104
- }
105
- });
106
-
107
- // src/rooms/index.ts
108
- var rooms_exports = {};
109
- __export(rooms_exports, {
110
- VenusRoom: () => exports.VenusRoom,
111
- initializeRoomsApi: () => initializeRoomsApi,
112
- setupRoomNotifications: () => setupRoomNotifications
113
- });
114
- function bindMethod(target, targetKey, source, sourceKey) {
115
- const key = sourceKey ?? targetKey;
116
- const fn = source?.[key];
117
- if (typeof fn === "function") {
118
- target[targetKey] = fn.bind(source);
119
- return true;
120
- }
121
- return false;
122
- }
123
- function setupRoomNotifications(transport, getSubscriptions) {
124
- console.log("[Venus Rooms] Setting up room notification listeners");
125
- return transport.onVenusMessage((message) => {
126
- const subscriptions = getSubscriptions();
127
- if (!subscriptions) {
128
- return;
129
- }
130
- if (message.type === "H5_ROOM_DATA_UPDATED") {
131
- const messageData = message.data;
132
- const { roomId, roomData } = messageData;
133
- if (!roomId) return;
134
- const callbacks = subscriptions.data?.[roomId] || [];
135
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
136
- console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
137
- callbacks.forEach((callback) => {
138
- try {
139
- callback(roomData);
140
- } catch (error) {
141
- console.error("[Venus Rooms] Error in room data callback:", error);
142
- throw error;
143
- }
144
- });
145
- allEventsCallbacks.forEach((callback) => {
146
- try {
147
- callback({ type: message.type, ...messageData });
148
- } catch (error) {
149
- console.error("[Venus Rooms] Error in allEvents callback:", error);
150
- throw error;
151
- }
152
- });
153
- }
154
- if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
155
- const messageData = message.data;
156
- const { roomId } = messageData;
157
- if (!roomId) return;
158
- const callbacks = subscriptions.messages?.[roomId] || [];
159
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
160
- console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
161
- callbacks.forEach((callback) => {
162
- try {
163
- callback(messageData);
164
- } catch (error) {
165
- console.error("[Venus Rooms] Error in room message callback:", error);
166
- throw error;
167
- }
168
- });
169
- allEventsCallbacks.forEach((callback) => {
170
- try {
171
- callback({ type: message.type, ...messageData });
172
- } catch (error) {
173
- console.error("[Venus Rooms] Error in allEvents callback:", error);
174
- throw error;
175
- }
176
- });
177
- }
178
- if (message.type === "app:h5:proposedMoveValidationUpdated") {
179
- const messageData = message.data;
180
- const { roomId } = messageData;
181
- if (!roomId) return;
182
- const callbacks = subscriptions.gameEvents?.[roomId] || [];
183
- const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
184
- console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
185
- callbacks.forEach((callback) => {
186
- try {
187
- callback(messageData);
188
- } catch (error) {
189
- console.error("[Venus Rooms] Error in game event callback:", error);
190
- throw error;
191
- }
192
- });
193
- allEventsCallbacks.forEach((callback) => {
194
- try {
195
- callback({ type: message.type, ...messageData });
196
- } catch (error) {
197
- console.error("[Venus Rooms] Error in allEvents callback:", error);
198
- throw error;
199
- }
200
- });
201
- }
202
- });
203
- }
204
- function initializeRoomsApi(venusApi, host) {
205
- const roomsApi = host?.rooms;
206
- if (!roomsApi) {
207
- console.warn(
208
- "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
209
- );
210
- return;
211
- }
212
- const venus = venusApi;
213
- const existingNamespace = venus.rooms || {};
214
- const roomsNamespace = Object.assign({}, existingNamespace);
215
- const namespaceBindings = [
216
- ["create", "createRoom"],
217
- ["joinOrCreate", "joinOrCreateRoom"],
218
- ["joinByCode", "joinRoomByCode"],
219
- ["list", "getUserRooms"],
220
- ["subscribeToRoom", "subscribe"],
221
- ["updateRoomData", "updateData"],
222
- ["getRoomData", "getData"],
223
- ["sendRoomMessage", "sendMessage"],
224
- ["leaveRoom", "leave"],
225
- ["startRoomGame", "startGame"],
226
- ["proposeMove"],
227
- ["validateMove"]
228
- ];
229
- namespaceBindings.forEach(([targetKey, sourceKey]) => {
230
- bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
231
- });
232
- venus.rooms = roomsNamespace;
233
- }
234
- var init_rooms = __esm({
235
- "src/rooms/index.ts"() {
236
- init_RoomsApi();
237
- init_VenusRoom();
238
- }
239
- });
240
-
241
7
  // src/VenusMessageId.ts
242
8
  var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
243
9
  VenusMessageId2["H5_RESPONSE"] = "H5_RESPONSE";
@@ -284,10 +50,6 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
284
50
  VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
285
51
  VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
286
52
  VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
287
- VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
288
- VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
289
- VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
290
- VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
291
53
  VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
292
54
  VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
293
55
  VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
@@ -329,6 +91,9 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
329
91
  VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
330
92
  VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
331
93
  VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
94
+ VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
95
+ VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
96
+ VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
332
97
  VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
333
98
  VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
334
99
  VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
@@ -588,7 +353,7 @@ var MockAvatarApi = class {
588
353
  async deleteAvatar() {
589
354
  console.log(`[Venus Mock] Deleting avatar3d config`);
590
355
  const venusApi = this._venusApi;
591
- const currentProfile = venusApi.getCurrentProfile();
356
+ const currentProfile = venusApi.getProfile();
592
357
  const profileId = currentProfile?.id || "default_profile";
593
358
  localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
594
359
  console.log(
@@ -603,7 +368,7 @@ var MockAvatarApi = class {
603
368
  console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
604
369
  config = await this.selectAvatarConfig(avatar3dId, false);
605
370
  } else {
606
- const currentProfile = venusApi.getCurrentProfile();
371
+ const currentProfile = venusApi.getProfile();
607
372
  const profileId = currentProfile?.id || "default_profile";
608
373
  console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
609
374
  console.log(
@@ -620,7 +385,7 @@ var MockAvatarApi = class {
620
385
  async saveAvatar(config) {
621
386
  console.log(`[Venus Mock] Saving avatar3d config:`, config);
622
387
  const venusApi = this._venusApi;
623
- const currentProfile = venusApi.getCurrentProfile();
388
+ const currentProfile = venusApi.getProfile();
624
389
  const profileId = currentProfile?.id || "default_profile";
625
390
  localStorage.setItem(
626
391
  `venus-mock-avatar3d-${profileId}`,
@@ -1151,9 +916,15 @@ var HostCdnApi = class {
1151
916
 
1152
917
  // src/cdn/MockCdnApi.ts
1153
918
  var MockCdnApi = class {
1154
- constructor() {
1155
- __publicField(this, "baseUrl");
1156
- this.baseUrl = "https://venus-static-01293ak.web.app/";
919
+ constructor(venusApi) {
920
+ __publicField(this, "venusApi");
921
+ this.venusApi = venusApi;
922
+ }
923
+ get baseUrl() {
924
+ return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
925
+ }
926
+ get forceRemoteCdn() {
927
+ return this.venusApi._mock?.cdnForceRemote ?? false;
1157
928
  }
1158
929
  async fetchBlob(path, options) {
1159
930
  const controller = new AbortController();
@@ -1190,6 +961,10 @@ var MockCdnApi = class {
1190
961
  return subPath;
1191
962
  }
1192
963
  const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
964
+ const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
965
+ if (isLocalhost && !this.forceRemoteCdn) {
966
+ return `/${cleanSubPath}`;
967
+ }
1193
968
  const pathParts = cleanSubPath.split("/");
1194
969
  const encodedParts = pathParts.map((part, index) => {
1195
970
  return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
@@ -1311,6 +1086,212 @@ function initializeCdn(venusApi, host) {
1311
1086
  venusApi.cdn = host.cdn;
1312
1087
  }
1313
1088
 
1089
+ // src/device/HostDeviceApi.ts
1090
+ var HostDeviceApi = class {
1091
+ constructor(venusApi) {
1092
+ __publicField(this, "venusApi");
1093
+ this.venusApi = venusApi;
1094
+ }
1095
+ getDevice() {
1096
+ const device = this.venusApi._deviceData;
1097
+ if (!device) {
1098
+ throw new Error(
1099
+ "[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
1100
+ );
1101
+ }
1102
+ return device;
1103
+ }
1104
+ };
1105
+
1106
+ // src/device/MockDeviceApi.ts
1107
+ var MockDeviceApi = class {
1108
+ constructor(venusApi) {
1109
+ __publicField(this, "venusApi");
1110
+ this.venusApi = venusApi;
1111
+ }
1112
+ getDevice() {
1113
+ const width = typeof window !== "undefined" ? window.innerWidth : 400;
1114
+ const height = typeof window !== "undefined" ? window.innerHeight : 800;
1115
+ return {
1116
+ screenSize: { width, height },
1117
+ viewportSize: {
1118
+ width: width - 20,
1119
+ // account for safe area
1120
+ height: height - 20
1121
+ },
1122
+ orientation: width > height ? "landscape" : "portrait",
1123
+ pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
1124
+ fontScale: 1,
1125
+ deviceType: width > 768 ? "tablet" : "phone",
1126
+ hapticsEnabled: false,
1127
+ haptics: { supported: false, enabled: false }
1128
+ };
1129
+ }
1130
+ };
1131
+
1132
+ // src/environment/HostEnvironmentApi.ts
1133
+ var HostEnvironmentApi = class {
1134
+ constructor(venusApi) {
1135
+ __publicField(this, "venusApi");
1136
+ this.venusApi = venusApi;
1137
+ }
1138
+ getEnvironment() {
1139
+ const environment = this.venusApi._environmentData;
1140
+ if (!environment) {
1141
+ throw new Error(
1142
+ "[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
1143
+ );
1144
+ }
1145
+ return environment;
1146
+ }
1147
+ };
1148
+
1149
+ // src/environment/MockEnvironmentApi.ts
1150
+ var MockEnvironmentApi = class {
1151
+ constructor(venusApi) {
1152
+ __publicField(this, "venusApi");
1153
+ this.venusApi = venusApi;
1154
+ }
1155
+ getEnvironment() {
1156
+ const getBrowser = () => {
1157
+ if (typeof navigator === "undefined") return "unknown";
1158
+ const userAgent = navigator.userAgent;
1159
+ if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
1160
+ if (/firefox|fxios/i.test(userAgent)) return "firefox";
1161
+ if (/safari/i.test(userAgent)) return "safari";
1162
+ if (/edg/i.test(userAgent)) return "edge";
1163
+ if (/opera|opr/i.test(userAgent)) return "opera";
1164
+ return "unknown";
1165
+ };
1166
+ return {
1167
+ isDevelopment: true,
1168
+ platform: "web",
1169
+ platformVersion: "mock-1.0",
1170
+ browserInfo: {
1171
+ browser: getBrowser(),
1172
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
1173
+ isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
1174
+ isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
1175
+ language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
1176
+ }
1177
+ };
1178
+ }
1179
+ };
1180
+
1181
+ // src/system/HostSystemApi.ts
1182
+ var HostSystemApi = class {
1183
+ constructor(deviceApi, environmentApi, venusApi) {
1184
+ __publicField(this, "deviceApi");
1185
+ __publicField(this, "environmentApi");
1186
+ __publicField(this, "venusApi");
1187
+ this.deviceApi = deviceApi;
1188
+ this.environmentApi = environmentApi;
1189
+ this.venusApi = venusApi;
1190
+ }
1191
+ getDevice() {
1192
+ return this.deviceApi.getDevice();
1193
+ }
1194
+ getEnvironment() {
1195
+ return this.environmentApi.getEnvironment();
1196
+ }
1197
+ getSafeArea() {
1198
+ const safeArea = this.venusApi._safeAreaData;
1199
+ if (!safeArea) {
1200
+ throw new Error(
1201
+ "[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
1202
+ );
1203
+ }
1204
+ return { ...safeArea };
1205
+ }
1206
+ isMobile() {
1207
+ const environment = this.environmentApi.getEnvironment();
1208
+ if (environment.platform === "ios" || environment.platform === "android") {
1209
+ return true;
1210
+ }
1211
+ if (environment.browserInfo) {
1212
+ return environment.browserInfo.isMobile;
1213
+ }
1214
+ return true;
1215
+ }
1216
+ isWeb() {
1217
+ const environment = this.environmentApi.getEnvironment();
1218
+ if (environment.platform === "web") {
1219
+ return true;
1220
+ }
1221
+ if (environment.browserInfo && !environment.browserInfo.isMobile) {
1222
+ return true;
1223
+ }
1224
+ return false;
1225
+ }
1226
+ };
1227
+
1228
+ // src/system/MockSystemApi.ts
1229
+ var MockSystemApi = class {
1230
+ constructor(deviceApi, environmentApi, venusApi) {
1231
+ __publicField(this, "deviceApi");
1232
+ __publicField(this, "environmentApi");
1233
+ __publicField(this, "venusApi");
1234
+ this.deviceApi = deviceApi;
1235
+ this.environmentApi = environmentApi;
1236
+ this.venusApi = venusApi;
1237
+ }
1238
+ getDevice() {
1239
+ return this.deviceApi.getDevice();
1240
+ }
1241
+ getEnvironment() {
1242
+ return this.environmentApi.getEnvironment();
1243
+ }
1244
+ getSafeArea() {
1245
+ const safeArea = this.venusApi._safeAreaData;
1246
+ if (!safeArea) {
1247
+ return {
1248
+ top: 0,
1249
+ right: 0,
1250
+ bottom: 34,
1251
+ left: 0
1252
+ };
1253
+ }
1254
+ return { ...safeArea };
1255
+ }
1256
+ isMobile() {
1257
+ const environment = this.environmentApi.getEnvironment();
1258
+ if (environment.platform === "ios" || environment.platform === "android") {
1259
+ return true;
1260
+ }
1261
+ if (environment.browserInfo) {
1262
+ return environment.browserInfo.isMobile;
1263
+ }
1264
+ return true;
1265
+ }
1266
+ isWeb() {
1267
+ const environment = this.environmentApi.getEnvironment();
1268
+ if (environment.platform === "web") {
1269
+ return true;
1270
+ }
1271
+ if (environment.browserInfo && !environment.browserInfo.isMobile) {
1272
+ return true;
1273
+ }
1274
+ return false;
1275
+ }
1276
+ };
1277
+
1278
+ // src/system/index.ts
1279
+ function initializeSystem(venusApi, host) {
1280
+ venusApi.system = host.system;
1281
+ venusApi.isMobile = () => {
1282
+ console.warn(
1283
+ "[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
1284
+ );
1285
+ return host.system.isMobile();
1286
+ };
1287
+ venusApi.isWeb = () => {
1288
+ console.warn(
1289
+ "[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
1290
+ );
1291
+ return host.system.isWeb();
1292
+ };
1293
+ }
1294
+
1314
1295
  // src/features/RpcFeaturesApi.ts
1315
1296
  var RpcFeaturesApi = class {
1316
1297
  constructor(rcpClient) {
@@ -1793,13 +1774,8 @@ var MockNotificationsApi = class {
1793
1774
  async cancelNotification(notificationId) {
1794
1775
  const venusApi = this.venusApi;
1795
1776
  if (isWebPlatform()) {
1796
- console.log(
1797
- "[Venus Mock] Cancel notification on web platform (simulated):",
1798
- notificationId
1799
- );
1800
1777
  return true;
1801
1778
  }
1802
- console.log("[Venus Mock] Cancel local notification:", notificationId);
1803
1779
  await createMockDelay(MOCK_DELAYS.short);
1804
1780
  if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
1805
1781
  delete venusApi._mock.scheduledNotifications[notificationId];
@@ -1809,12 +1785,8 @@ var MockNotificationsApi = class {
1809
1785
  }
1810
1786
  async getAllScheduledLocalNotifications() {
1811
1787
  if (isWebPlatform()) {
1812
- console.log(
1813
- "[Venus Mock] Get notifications on web platform (returning empty list)"
1814
- );
1815
1788
  return [];
1816
1789
  }
1817
- console.log("[Venus Mock] Get all scheduled local notifications");
1818
1790
  await createMockDelay(MOCK_DELAYS.short);
1819
1791
  const venusApi = this.venusApi;
1820
1792
  const notifications = venusApi._mock.scheduledNotifications || {};
@@ -1822,10 +1794,8 @@ var MockNotificationsApi = class {
1822
1794
  }
1823
1795
  async isLocalNotificationsEnabled() {
1824
1796
  if (isWebPlatform()) {
1825
- console.log("[Venus Mock] Notifications not available on web platform");
1826
1797
  return false;
1827
1798
  }
1828
- console.log("[Venus Mock] Check if local notifications are enabled");
1829
1799
  await createMockDelay(MOCK_DELAYS.short);
1830
1800
  const venusApi = this.venusApi;
1831
1801
  const isEnabled = venusApi._mock.notificationsEnabled !== false;
@@ -1834,9 +1804,6 @@ var MockNotificationsApi = class {
1834
1804
  async scheduleAsync(title, body, seconds, notificationId, options) {
1835
1805
  const { priority = 50, groupId, payload } = options || {};
1836
1806
  if (isWebPlatform()) {
1837
- console.log(
1838
- "[Venus Mock] Notifications not supported on web platform, simulating success"
1839
- );
1840
1807
  console.info(
1841
1808
  "\u{1F514} [Venus Mock] Notification would be scheduled:",
1842
1809
  title || "Untitled",
@@ -1847,14 +1814,11 @@ var MockNotificationsApi = class {
1847
1814
  const mockId = `mock-web-notification-${Date.now()}`;
1848
1815
  return mockId;
1849
1816
  }
1850
- console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
1851
1817
  const venusApi = this.venusApi;
1852
1818
  if (!venusApi._mock.pendingRequests) {
1853
- console.log("[Venus Mock] Initializing pendingRequests");
1854
1819
  venusApi._mock.pendingRequests = {};
1855
1820
  }
1856
1821
  const requestId = Date.now().toString();
1857
- console.log("[Venus Mock] Creating request with ID:", requestId);
1858
1822
  return new Promise((resolve) => {
1859
1823
  venusApi._mock.pendingRequests[requestId] = { resolve };
1860
1824
  const id = notificationId || `mock-notification-${Date.now()}`;
@@ -1876,13 +1840,8 @@ var MockNotificationsApi = class {
1876
1840
  async setLocalNotificationsEnabled(enabled) {
1877
1841
  const venusApi = this.venusApi;
1878
1842
  if (isWebPlatform()) {
1879
- console.log(
1880
- "[Venus Mock] Set notifications enabled on web platform (simulated):",
1881
- enabled
1882
- );
1883
1843
  return true;
1884
1844
  }
1885
- console.log("[Venus Mock] Set local notifications enabled:", enabled);
1886
1845
  await createMockDelay(MOCK_DELAYS.short);
1887
1846
  venusApi._mock.notificationsEnabled = enabled;
1888
1847
  return enabled;
@@ -2107,16 +2066,20 @@ function initializePopups(venusApi, host) {
2107
2066
 
2108
2067
  // src/profile/HostProfileApi.ts
2109
2068
  var HostProfileApi = class {
2069
+ constructor(venusApi) {
2070
+ __publicField(this, "venusApi");
2071
+ this.venusApi = venusApi;
2072
+ }
2110
2073
  getCurrentProfile() {
2111
- const profile = window.venus?.profile;
2074
+ const profile = this.venusApi._profileData;
2112
2075
  if (!profile) {
2113
2076
  throw new Error(
2114
- "[Venus SDK] Host profile handshake did not complete. Await VenusAPI.initializeAsync() so INIT_SDK can deliver the profile before calling profile APIs."
2077
+ "[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
2115
2078
  );
2116
2079
  }
2117
2080
  if (!profile.id || !profile.username) {
2118
2081
  throw new Error(
2119
- "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply real credentials before rooms APIs are used."
2082
+ "[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
2120
2083
  );
2121
2084
  }
2122
2085
  return {
@@ -2130,6 +2093,10 @@ var HostProfileApi = class {
2130
2093
 
2131
2094
  // src/profile/MockProfileApi.ts
2132
2095
  var MockProfileApi = class {
2096
+ constructor(venusApi) {
2097
+ __publicField(this, "venusApi");
2098
+ this.venusApi = venusApi;
2099
+ }
2133
2100
  getCurrentProfile() {
2134
2101
  return {
2135
2102
  id: "mock_profile_123",
@@ -2142,11 +2109,22 @@ var MockProfileApi = class {
2142
2109
 
2143
2110
  // src/profile/index.ts
2144
2111
  function initializeProfile(venusApi, host) {
2112
+ venusApi.getProfile = () => {
2113
+ return host.profile.getCurrentProfile();
2114
+ };
2145
2115
  venusApi.getCurrentProfile = () => {
2116
+ console.warn(
2117
+ "[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
2118
+ );
2146
2119
  return host.profile.getCurrentProfile();
2147
2120
  };
2148
2121
  }
2149
2122
 
2123
+ // src/utils/idGenerator.ts
2124
+ function generateId() {
2125
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2126
+ }
2127
+
2150
2128
  // src/rpc/RpcClient.ts
2151
2129
  var RpcClient = class {
2152
2130
  constructor() {
@@ -2189,7 +2167,7 @@ var RpcClient = class {
2189
2167
  }
2190
2168
  async call(method, args, timeout = 5e3) {
2191
2169
  return new Promise((resolve, reject) => {
2192
- const id = this.generateId();
2170
+ const id = generateId();
2193
2171
  this.addPendingCall(id, resolve, reject);
2194
2172
  const request = {
2195
2173
  type: "rpc-request",
@@ -2226,9 +2204,6 @@ var RpcClient = class {
2226
2204
  getPendingCall(id) {
2227
2205
  return this.pendingCalls.get(id);
2228
2206
  }
2229
- generateId() {
2230
- return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
2231
- }
2232
2207
  handleRpcResponse(response) {
2233
2208
  const pending = this.getPendingCall(response.id);
2234
2209
  if (!pending) {
@@ -2250,47 +2225,464 @@ var RpcClient = class {
2250
2225
  }
2251
2226
  };
2252
2227
 
2253
- // src/index.ts
2254
- init_rooms();
2255
-
2256
- // src/storage/MockStorageApi.ts
2257
- function createMockStorageApi(storageType, appUrl) {
2258
- const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2259
- let prefix;
2260
- let syncDelay = 0;
2261
- switch (storageType) {
2262
- case "deviceCache":
2263
- prefix = "venus:app";
2264
- syncDelay = 0;
2265
- break;
2266
- case "appStorage":
2267
- prefix = "venus:app";
2268
- syncDelay = 100;
2269
- break;
2270
- case "globalStorage":
2271
- prefix = "venus:global";
2272
- syncDelay = 100;
2273
- break;
2274
- default:
2275
- throw new Error(`Unknown storage type: ${storageType}`);
2276
- }
2277
- prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2278
- return new MockStorageApi(prefix, syncDelay);
2279
- }
2280
- var MockStorageApi = class {
2281
- constructor(prefix, syncDelay) {
2282
- __publicField(this, "prefix");
2283
- __publicField(this, "syncDelay");
2284
- this.prefix = prefix;
2285
- this.syncDelay = syncDelay;
2228
+ // src/rooms/VenusRoom.ts
2229
+ var VenusRoom = class {
2230
+ constructor(roomData) {
2231
+ __publicField(this, "id");
2232
+ __publicField(this, "name");
2233
+ __publicField(this, "players");
2234
+ __publicField(this, "maxPlayers");
2235
+ __publicField(this, "gameType");
2236
+ __publicField(this, "appId");
2237
+ __publicField(this, "type");
2238
+ __publicField(this, "createdBy");
2239
+ __publicField(this, "createdAt");
2240
+ __publicField(this, "updatedAt");
2241
+ __publicField(this, "isPrivate");
2242
+ __publicField(this, "status");
2243
+ __publicField(this, "customMetadata");
2244
+ __publicField(this, "admins");
2245
+ __publicField(this, "roomCode");
2246
+ __publicField(this, "description");
2247
+ __publicField(this, "data");
2248
+ __publicField(this, "version");
2249
+ this.id = roomData.id;
2250
+ this.name = roomData.name;
2251
+ this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
2252
+ this.maxPlayers = roomData.maxPlayers;
2253
+ this.gameType = roomData.gameType;
2254
+ this.appId = roomData.appId;
2255
+ this.type = roomData.type;
2256
+ this.createdBy = roomData.createdBy;
2257
+ this.createdAt = roomData.createdAt;
2258
+ this.updatedAt = roomData.updatedAt;
2259
+ this.isPrivate = roomData.isPrivate;
2260
+ this.status = roomData.status;
2261
+ this.customMetadata = roomData.customMetadata || {};
2262
+ this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
2263
+ this.roomCode = roomData.roomCode;
2264
+ this.description = roomData.description;
2265
+ this.data = roomData.data || {};
2266
+ this.version = roomData.version;
2286
2267
  }
2287
- async clear() {
2288
- const fullLength = localStorage.length;
2289
- for (let i = 0; i < fullLength; i++) {
2290
- const fullKey = localStorage.key(i);
2291
- if (fullKey && fullKey.startsWith(this.prefix)) {
2292
- localStorage.removeItem(fullKey);
2293
- }
2268
+ };
2269
+
2270
+ // src/rooms/setupRoomNotifications.ts
2271
+ function invokeCallbacks(callbacks, event, context) {
2272
+ callbacks.forEach((callback) => {
2273
+ try {
2274
+ callback(event);
2275
+ } catch (error) {
2276
+ console.error(`[Venus SDK] Error in ${context} callback:`, error);
2277
+ throw error;
2278
+ }
2279
+ });
2280
+ }
2281
+ function setupRoomNotifications(transport, getSubscriptions) {
2282
+ return transport.onVenusMessage((message) => {
2283
+ const subscriptions = getSubscriptions();
2284
+ if (!subscriptions) {
2285
+ return;
2286
+ }
2287
+ if (message.type === "H5_ROOM_DATA_UPDATED") {
2288
+ const messageData = message.data;
2289
+ const { roomId, roomData } = messageData;
2290
+ if (!roomId) return;
2291
+ const callbacks = subscriptions.data[roomId] || [];
2292
+ const event = {
2293
+ type: "H5_ROOM_DATA_UPDATED",
2294
+ roomId,
2295
+ roomData,
2296
+ timestamp: messageData.timestamp
2297
+ };
2298
+ invokeCallbacks(callbacks, event, "room data");
2299
+ }
2300
+ if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
2301
+ const messageData = message.data;
2302
+ const { roomId } = messageData;
2303
+ if (!roomId) return;
2304
+ const callbacks = subscriptions.messages[roomId] || [];
2305
+ const event = {
2306
+ type: message.type,
2307
+ roomId,
2308
+ message: messageData.message,
2309
+ timestamp: messageData.timestamp
2310
+ };
2311
+ invokeCallbacks(callbacks, event, "room message");
2312
+ }
2313
+ if (message.type === "app:h5:proposedMoveValidationUpdated") {
2314
+ const messageData = message.data;
2315
+ const { roomId } = messageData;
2316
+ if (!roomId) return;
2317
+ const callbacks = subscriptions.gameEvents[roomId] || [];
2318
+ const event = {
2319
+ type: "app:h5:proposedMoveValidationUpdated",
2320
+ roomId,
2321
+ proposedMoveData: messageData.proposedMoveData,
2322
+ proposedMoveId: messageData.proposedMoveId,
2323
+ changeType: messageData.changeType,
2324
+ timestamp: messageData.timestamp
2325
+ };
2326
+ invokeCallbacks(callbacks, event, "game event");
2327
+ }
2328
+ });
2329
+ }
2330
+
2331
+ // src/rooms/RpcRoomsApi.ts
2332
+ var RpcRoomsApi = class {
2333
+ constructor(rpcClient) {
2334
+ __publicField(this, "rpcClient");
2335
+ __publicField(this, "subscriptions");
2336
+ this.rpcClient = rpcClient;
2337
+ this.subscriptions = {
2338
+ data: {},
2339
+ messages: {},
2340
+ gameEvents: {}
2341
+ };
2342
+ }
2343
+ /**
2344
+ * Get the subscription state for external access (used by setupRoomNotifications)
2345
+ */
2346
+ getSubscriptions() {
2347
+ return this.subscriptions;
2348
+ }
2349
+ /**
2350
+ * Set up room notification routing from the transport
2351
+ */
2352
+ setupNotifications(transport) {
2353
+ setupRoomNotifications(transport, () => this.getSubscriptions());
2354
+ }
2355
+ async createRoomAsync(options) {
2356
+ const response = await this.rpcClient.call(
2357
+ "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
2358
+ {
2359
+ options
2360
+ }
2361
+ );
2362
+ if (response.success === false) {
2363
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
2364
+ throw new Error(errorMessage);
2365
+ }
2366
+ const room = new VenusRoom(response.roomData);
2367
+ return room;
2368
+ }
2369
+ async joinOrCreateRoomAsync(options) {
2370
+ const response = await this.rpcClient.call(
2371
+ "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
2372
+ {
2373
+ options
2374
+ }
2375
+ );
2376
+ if (response.success === false) {
2377
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
2378
+ throw new Error(errorMessage);
2379
+ }
2380
+ const room = new VenusRoom(response.value.roomData);
2381
+ return {
2382
+ action: response.value.action,
2383
+ room,
2384
+ playersJoined: response.value.playersJoined
2385
+ };
2386
+ }
2387
+ async joinRoomByCodeAsync(roomCode) {
2388
+ const response = await this.rpcClient.call(
2389
+ "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
2390
+ {
2391
+ roomCode
2392
+ }
2393
+ );
2394
+ if (response?.success === false) {
2395
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
2396
+ throw new Error(errorMessage);
2397
+ }
2398
+ const room = new VenusRoom(response.roomData);
2399
+ return room;
2400
+ }
2401
+ // Get user's rooms with optional filtering
2402
+ async getUserRoomsAsync(options = {}) {
2403
+ const response = await this.rpcClient.call(
2404
+ "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
2405
+ {
2406
+ includeArchived: options.includeArchived ?? false
2407
+ }
2408
+ );
2409
+ if (response?.success === false) {
2410
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
2411
+ throw new Error(errorMessage);
2412
+ }
2413
+ const venusRooms = [];
2414
+ for (const roomData of response.rooms) {
2415
+ if (!roomData.id) {
2416
+ console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
2417
+ continue;
2418
+ }
2419
+ try {
2420
+ const venusRoom = new VenusRoom(roomData);
2421
+ venusRooms.push(venusRoom);
2422
+ } catch (error) {
2423
+ console.warn(
2424
+ "[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
2425
+ error,
2426
+ roomData
2427
+ );
2428
+ }
2429
+ }
2430
+ return venusRooms;
2431
+ }
2432
+ async updateRoomDataAsync(room, updates, options = {}) {
2433
+ const response = await this.rpcClient.call(
2434
+ "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
2435
+ {
2436
+ roomId: room.id,
2437
+ updates,
2438
+ merge: options.merge ?? true
2439
+ }
2440
+ );
2441
+ if (response?.success === false) {
2442
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
2443
+ throw new Error(errorMessage);
2444
+ }
2445
+ }
2446
+ async getRoomDataAsync(room) {
2447
+ const response = await this.rpcClient.call(
2448
+ "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
2449
+ {
2450
+ roomId: room.id
2451
+ }
2452
+ );
2453
+ if (response?.success === false) {
2454
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
2455
+ throw new Error(errorMessage);
2456
+ }
2457
+ return response.data;
2458
+ }
2459
+ async sendRoomMessageAsync(venusRoom, request) {
2460
+ const response = await this.rpcClient.call(
2461
+ "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
2462
+ {
2463
+ roomId: venusRoom.id,
2464
+ message: request.message,
2465
+ metadata: request.metadata
2466
+ }
2467
+ );
2468
+ if (response?.success === false) {
2469
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
2470
+ throw new Error(errorMessage);
2471
+ }
2472
+ return response.messageId;
2473
+ }
2474
+ async leaveRoomAsync(room) {
2475
+ const response = await this.rpcClient.call(
2476
+ "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
2477
+ {
2478
+ roomId: room.id
2479
+ }
2480
+ );
2481
+ if (response?.success === false) {
2482
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
2483
+ throw new Error(errorMessage);
2484
+ }
2485
+ }
2486
+ async startRoomGameAsync(room, options = {}) {
2487
+ const response = await this.rpcClient.call(
2488
+ "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
2489
+ {
2490
+ roomId: room.id,
2491
+ gameConfig: options.gameConfig ?? {},
2492
+ turnOrder: options.turnOrder ?? null
2493
+ }
2494
+ );
2495
+ if (response?.success === false) {
2496
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
2497
+ throw new Error(errorMessage);
2498
+ }
2499
+ }
2500
+ async proposeMoveAsync(room, proposalPayload) {
2501
+ const response = await this.rpcClient.call(
2502
+ "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
2503
+ {
2504
+ roomId: room.id,
2505
+ gameSpecificState: proposalPayload.gameSpecificState,
2506
+ moveType: proposalPayload.moveType,
2507
+ clientContext: proposalPayload.clientContext,
2508
+ clientProposalId: proposalPayload.clientProposalId
2509
+ }
2510
+ );
2511
+ if (response?.success === false) {
2512
+ const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
2513
+ throw new Error(errorMessage);
2514
+ }
2515
+ return response.data;
2516
+ }
2517
+ async validateMoveAsync(_room, moveId, verdict) {
2518
+ return {
2519
+ success: true,
2520
+ moveId,
2521
+ isValid: verdict.isValid,
2522
+ reason: verdict.reason
2523
+ };
2524
+ }
2525
+ async subscribeAsync(room, options = {}) {
2526
+ const roomId = room.id;
2527
+ const existingData = this.subscriptions.data[roomId];
2528
+ const existingMessages = this.subscriptions.messages[roomId];
2529
+ const existingGameEvents = this.subscriptions.gameEvents[roomId];
2530
+ const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
2531
+ const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
2532
+ const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
2533
+ if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
2534
+ try {
2535
+ await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
2536
+ roomId,
2537
+ subscribeToData,
2538
+ subscribeToMessages,
2539
+ subscribeToProposedMoves
2540
+ });
2541
+ } catch (error) {
2542
+ console.error("[Venus SDK] Failed to set up room subscription:", error);
2543
+ throw error;
2544
+ }
2545
+ }
2546
+ if (options.onData) {
2547
+ if (!this.subscriptions.data[roomId]) {
2548
+ this.subscriptions.data[roomId] = [];
2549
+ }
2550
+ this.subscriptions.data[roomId].push(options.onData);
2551
+ }
2552
+ if (options.onMessages) {
2553
+ if (!this.subscriptions.messages[roomId]) {
2554
+ this.subscriptions.messages[roomId] = [];
2555
+ }
2556
+ this.subscriptions.messages[roomId].push(options.onMessages);
2557
+ }
2558
+ if (options.onGameEvents) {
2559
+ if (!this.subscriptions.gameEvents[roomId]) {
2560
+ this.subscriptions.gameEvents[roomId] = [];
2561
+ }
2562
+ this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
2563
+ }
2564
+ let disposed = false;
2565
+ return () => {
2566
+ if (disposed) return;
2567
+ disposed = true;
2568
+ if (options.onData) {
2569
+ const callbacks = this.subscriptions.data[roomId];
2570
+ if (callbacks) {
2571
+ const index = callbacks.indexOf(options.onData);
2572
+ if (index > -1) {
2573
+ callbacks.splice(index, 1);
2574
+ }
2575
+ }
2576
+ }
2577
+ if (options.onMessages) {
2578
+ const callbacks = this.subscriptions.messages[roomId];
2579
+ if (callbacks) {
2580
+ const index = callbacks.indexOf(options.onMessages);
2581
+ if (index > -1) {
2582
+ callbacks.splice(index, 1);
2583
+ }
2584
+ }
2585
+ }
2586
+ if (options.onGameEvents) {
2587
+ const callbacks = this.subscriptions.gameEvents[roomId];
2588
+ if (callbacks) {
2589
+ const index = callbacks.indexOf(options.onGameEvents);
2590
+ if (index > -1) {
2591
+ callbacks.splice(index, 1);
2592
+ }
2593
+ }
2594
+ }
2595
+ const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
2596
+ if (!hasAnySubscriptions) {
2597
+ this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
2598
+ roomId
2599
+ }).catch((error) => {
2600
+ console.error("[Venus SDK] Failed to clean up room subscription:", error);
2601
+ });
2602
+ }
2603
+ };
2604
+ }
2605
+ };
2606
+
2607
+ // src/rooms/index.ts
2608
+ function bindMethod(target, targetKey, source, sourceKey) {
2609
+ const key = sourceKey ?? targetKey;
2610
+ const fn = source?.[key];
2611
+ if (typeof fn === "function") {
2612
+ target[targetKey] = fn.bind(source);
2613
+ return true;
2614
+ }
2615
+ return false;
2616
+ }
2617
+ function initializeRoomsApi(venusApi, host) {
2618
+ const roomsApi = host?.rooms;
2619
+ if (!roomsApi) {
2620
+ console.warn(
2621
+ "[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
2622
+ );
2623
+ return;
2624
+ }
2625
+ const venus = venusApi;
2626
+ const existingNamespace = venus.rooms || {};
2627
+ const roomsNamespace = Object.assign({}, existingNamespace);
2628
+ const namespaceBindings = [
2629
+ ["createRoomAsync"],
2630
+ ["joinOrCreateRoomAsync"],
2631
+ ["joinRoomByCodeAsync"],
2632
+ ["getUserRoomsAsync"],
2633
+ ["subscribeAsync"],
2634
+ ["updateRoomDataAsync"],
2635
+ ["getRoomDataAsync"],
2636
+ ["sendRoomMessageAsync"],
2637
+ ["leaveRoomAsync"],
2638
+ ["startRoomGameAsync"],
2639
+ ["proposeMoveAsync"],
2640
+ ["validateMoveAsync"]
2641
+ ];
2642
+ namespaceBindings.forEach(([targetKey, sourceKey]) => {
2643
+ bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
2644
+ });
2645
+ venus.rooms = roomsNamespace;
2646
+ }
2647
+
2648
+ // src/storage/MockStorageApi.ts
2649
+ function createMockStorageApi(storageType, appUrl) {
2650
+ const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2651
+ let prefix;
2652
+ let syncDelay = 0;
2653
+ switch (storageType) {
2654
+ case "deviceCache":
2655
+ prefix = "venus:app";
2656
+ syncDelay = 0;
2657
+ break;
2658
+ case "appStorage":
2659
+ prefix = "venus:app";
2660
+ syncDelay = 100;
2661
+ break;
2662
+ case "globalStorage":
2663
+ prefix = "venus:global";
2664
+ syncDelay = 100;
2665
+ break;
2666
+ default:
2667
+ throw new Error(`Unknown storage type: ${storageType}`);
2668
+ }
2669
+ prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
2670
+ return new MockStorageApi(prefix, syncDelay);
2671
+ }
2672
+ var MockStorageApi = class {
2673
+ constructor(prefix, syncDelay) {
2674
+ __publicField(this, "prefix");
2675
+ __publicField(this, "syncDelay");
2676
+ this.prefix = prefix;
2677
+ this.syncDelay = syncDelay;
2678
+ }
2679
+ async clear() {
2680
+ const fullLength = localStorage.length;
2681
+ for (let i = 0; i < fullLength; i++) {
2682
+ const fullKey = localStorage.key(i);
2683
+ if (fullKey && fullKey.startsWith(this.prefix)) {
2684
+ localStorage.removeItem(fullKey);
2685
+ }
2294
2686
  }
2295
2687
  await this.simulateSyncDelay();
2296
2688
  }
@@ -2486,24 +2878,20 @@ function initializeStorage(venusApiInstance, host) {
2486
2878
  venusApiInstance.globalStorage = host.globalStorage;
2487
2879
  }
2488
2880
 
2489
- // src/simulation/utils.ts
2490
- function sumContributions(contributions) {
2491
- const totals = {};
2492
- for (const profileId in contributions) {
2493
- for (const entityId in contributions[profileId]) {
2494
- const amount = contributions[profileId][entityId] || 0;
2495
- totals[entityId] = (totals[entityId] || 0) + amount;
2496
- }
2497
- }
2498
- return totals;
2499
- }
2500
-
2501
2881
  // src/simulation/RpcSimulationApi.ts
2502
2882
  var RpcSimulationApi = class {
2503
2883
  constructor(rpcClient) {
2504
2884
  __publicField(this, "rpcClient");
2505
2885
  __publicField(this, "_simulationConfig", null);
2886
+ __publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
2506
2887
  this.rpcClient = rpcClient;
2888
+ this.rpcClient.onNotification(
2889
+ "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
2890
+ this.handleSimulationUpdate.bind(this)
2891
+ );
2892
+ }
2893
+ isEnabled() {
2894
+ return true;
2507
2895
  }
2508
2896
  async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2509
2897
  return this.rpcClient.call(
@@ -2515,14 +2903,47 @@ var RpcSimulationApi = class {
2515
2903
  }
2516
2904
  );
2517
2905
  }
2518
- sumContributions(contributions) {
2519
- return sumContributions(contributions);
2906
+ async subscribeAsync(options) {
2907
+ this.ensureValidSubscribeOptions(options);
2908
+ const subscriptionId = generateId();
2909
+ this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
2910
+ try {
2911
+ await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
2912
+ subscriptionId,
2913
+ entities: options.entities,
2914
+ tags: options.tags,
2915
+ activeRuns: options.activeRuns,
2916
+ roomId: options.roomId
2917
+ });
2918
+ } catch (error) {
2919
+ this.subscriptionCallbacks.delete(subscriptionId);
2920
+ throw error;
2921
+ }
2922
+ let unsubscribed = false;
2923
+ return () => {
2924
+ if (unsubscribed) {
2925
+ return;
2926
+ }
2927
+ unsubscribed = true;
2928
+ this.subscriptionCallbacks.delete(subscriptionId);
2929
+ void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
2930
+ subscriptionId
2931
+ }).catch((error) => {
2932
+ console.error(
2933
+ "[Venus SDK] Failed to unsubscribe simulation listener",
2934
+ error
2935
+ );
2936
+ });
2937
+ };
2520
2938
  }
2521
2939
  executeBatchOperationsAsync(operations, validateOnly) {
2522
- return this.rpcClient.call("H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */, {
2523
- operations,
2524
- validateOnly
2525
- });
2940
+ return this.rpcClient.call(
2941
+ "H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
2942
+ {
2943
+ operations,
2944
+ validateOnly
2945
+ }
2946
+ );
2526
2947
  }
2527
2948
  async getAvailableItemsAsync(containerId, slotId) {
2528
2949
  const response = await this.rpcClient.call(
@@ -2545,17 +2966,23 @@ var RpcSimulationApi = class {
2545
2966
  );
2546
2967
  }
2547
2968
  assignItemToSlotAsync(containerId, slotId, itemId) {
2548
- return this.rpcClient.call("H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */, {
2549
- containerId,
2550
- slotId,
2551
- itemId
2552
- });
2969
+ return this.rpcClient.call(
2970
+ "H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
2971
+ {
2972
+ containerId,
2973
+ slotId,
2974
+ itemId
2975
+ }
2976
+ );
2553
2977
  }
2554
2978
  removeItemFromSlotAsync(containerId, slotId) {
2555
- return this.rpcClient.call("H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */, {
2556
- containerId,
2557
- slotId
2558
- });
2979
+ return this.rpcClient.call(
2980
+ "H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
2981
+ {
2982
+ containerId,
2983
+ slotId
2984
+ }
2985
+ );
2559
2986
  }
2560
2987
  async getSlotContainersAsync() {
2561
2988
  const response = await this.rpcClient.call(
@@ -2580,7 +3007,6 @@ var RpcSimulationApi = class {
2580
3007
  roomId
2581
3008
  }
2582
3009
  );
2583
- console.log("[Venus SDK] getStateAsync", response);
2584
3010
  if (response.configuration) {
2585
3011
  this._simulationConfig = response.configuration;
2586
3012
  }
@@ -2592,9 +3018,10 @@ var RpcSimulationApi = class {
2592
3018
  }
2593
3019
  const config = await this.rpcClient.call(
2594
3020
  "H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
2595
- {}
3021
+ {
3022
+ roomId
3023
+ }
2596
3024
  );
2597
- console.log("[Venus SDK] getConfigAsync", config);
2598
3025
  if (config) {
2599
3026
  this._simulationConfig = config;
2600
3027
  return config;
@@ -2602,14 +3029,17 @@ var RpcSimulationApi = class {
2602
3029
  throw new Error("No simulation configuration available");
2603
3030
  }
2604
3031
  executeRecipeAsync(recipeId, inputs, options) {
2605
- return this.rpcClient.call("H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */, {
2606
- recipeId,
2607
- inputs,
2608
- roomId: options?.roomId,
2609
- batchAmount: options?.batchAmount,
2610
- allowPartialBatch: options?.allowPartialBatch,
2611
- entity: options?.entity
2612
- });
3032
+ return this.rpcClient.call(
3033
+ "H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
3034
+ {
3035
+ recipeId,
3036
+ inputs,
3037
+ roomId: options?.roomId,
3038
+ batchAmount: options?.batchAmount,
3039
+ allowPartialBatch: options?.allowPartialBatch,
3040
+ entity: options?.entity
3041
+ }
3042
+ );
2613
3043
  }
2614
3044
  collectRecipeAsync(runId) {
2615
3045
  return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
@@ -2617,9 +3047,12 @@ var RpcSimulationApi = class {
2617
3047
  });
2618
3048
  }
2619
3049
  getActiveRunsAsync(options) {
2620
- return this.rpcClient.call("H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */, {
2621
- roomId: options?.roomId
2622
- });
3050
+ return this.rpcClient.call(
3051
+ "H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
3052
+ {
3053
+ roomId: options?.roomId
3054
+ }
3055
+ );
2623
3056
  }
2624
3057
  executeScopedRecipeAsync(recipeId, entity, inputs, options) {
2625
3058
  return this.rpcClient.call(
@@ -2689,583 +3122,52 @@ var RpcSimulationApi = class {
2689
3122
  );
2690
3123
  return response.value;
2691
3124
  }
2692
- };
2693
-
2694
- // src/simulation/MockSimulationApi.ts
2695
- function generateAppIdentifier2() {
2696
- if (typeof window === "undefined") return "unknown-app";
2697
- const url = window.location.href;
2698
- const match = url.match(/\/H5\/([^\/]+)/);
2699
- return match ? match[1] : "unknown-app";
2700
- }
2701
- var MockSimulationApi = class {
2702
- constructor(simulationConfig = null) {
2703
- __publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
2704
- // appIdentifier -> config
2705
- __publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
2706
- // appIdentifier -> config
2707
- __publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
2708
- // appIdentifier -> timers[]
2709
- __publicField(this, "appId");
2710
- __publicField(this, "providedSimulationConfig");
2711
- this.appId = generateAppIdentifier2();
2712
- this.providedSimulationConfig = simulationConfig;
2713
- }
2714
- sumContributions(contributions) {
2715
- return sumContributions(contributions);
2716
- }
2717
- async validateSlotAssignmentAsync(containerId, slotId, itemId) {
2718
- this.log("validateSlotAssignmentAsync called:", {
2719
- containerId,
2720
- slotId,
2721
- itemId
2722
- });
2723
- return { valid: true, message: "Mock validation successful" };
2724
- }
2725
- async executeBatchOperationsAsync(operations, validateOnly) {
2726
- this.log("executeBatchOperationsAsync called:", {
2727
- operations,
2728
- validateOnly
2729
- });
2730
- return {
2731
- success: true,
2732
- results: operations.map(() => ({ success: true }))
2733
- };
2734
- }
2735
- async getAvailableItemsAsync(containerId, slotId) {
2736
- console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
2737
- containerId,
2738
- slotId
2739
- });
2740
- const appIdentifier = generateAppIdentifier2();
2741
- const mockSimulationConfigs = this.mockSimulationConfigs;
2742
- const config = mockSimulationConfigs.get(appIdentifier) || {
2743
- entities: {}
2744
- };
2745
- const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
2746
- entityId,
2747
- quantity: 1,
2748
- metadata: entity.metadata,
2749
- powerPreview: 100
2750
- // Mock power value
2751
- }));
2752
- return availableItems;
2753
- }
2754
- async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
2755
- this.log("calculatePowerPreviewAsync called:", {
2756
- containerId,
2757
- slotId,
2758
- candidateItemId
2759
- });
2760
- return {
2761
- currentPower: 1e3,
2762
- previewPower: 1200,
2763
- powerDelta: 200,
2764
- breakdown: { base: 800, weapon: 200, armor: 200 }
2765
- };
2766
- }
2767
- async getSlotContainersAsync() {
2768
- this.log("getSlotContainersAsync called");
2769
- const appIdentifier = this.appId;
2770
- const mockSimulationConfigs = this.mockSimulationConfigs;
2771
- const config = mockSimulationConfigs.get(appIdentifier) || {
2772
- entities: {}
2773
- };
2774
- const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
2775
- entityId,
2776
- slots: entity.metadata?.slots,
2777
- isOwned: true
2778
- // Mock: assume all containers are owned
2779
- }));
2780
- return containers;
2781
- }
2782
- async getSlotAssignmentsAsync(containerId) {
2783
- this.log("getSlotAssignmentsAsync called for:", containerId);
2784
- return [];
2785
- }
2786
- async resolveFieldValueAsync(entityId, fieldPath, entity) {
2787
- this.log("resolveFieldValueAsync called:", {
2788
- entityId,
2789
- fieldPath,
2790
- entity
2791
- });
2792
- const mockValues = {
2793
- basePower: 850,
2794
- weaponPower: 300,
2795
- armorPower: 150,
2796
- total_power: 1300,
2797
- total_defense_power: 5e3
2798
- };
2799
- return mockValues[fieldPath] || 100;
2800
- }
2801
- async getEntityMetadataAsync(entityId) {
2802
- this.log("getEntityMetadataAsync called for:", entityId);
2803
- const mockSimulationConfigs = this.mockSimulationConfigs;
2804
- const appIdentifier = this.appId;
2805
- const config = mockSimulationConfigs.get(
2806
- appIdentifier
2807
- ) || {
2808
- entities: {}};
2809
- const entity = config.entities[entityId];
2810
- return entity?.metadata || {};
2811
- }
2812
- async collectRecipeAsync(runId) {
2813
- this.log("collectRecipeAsync called:", { runId });
2814
- const mockRewards = {
2815
- cash: Math.floor(Math.random() * 1e3) + 500,
2816
- experience: Math.floor(Math.random() * 50) + 25
2817
- };
2818
- return {
2819
- success: true,
2820
- runId,
2821
- rewards: mockRewards,
2822
- message: "Rewards collected successfully"
2823
- };
2824
- }
2825
- executeRecipeAsync(recipeId, inputs, options) {
2826
- this.log("executeRecipeAsync called:", {
2827
- recipeId,
2828
- inputs,
2829
- options
2830
- });
2831
- const appIdentifier = this.appId;
2832
- return this.executeRecipe(appIdentifier, recipeId, inputs);
2833
- }
2834
- async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
2835
- this.log("executeScopedRecipeAsync called:", {
2836
- recipeId,
2837
- entity,
2838
- inputs,
2839
- roomId: options?.roomId,
2840
- options
2841
- });
2842
- return {
2843
- success: true,
2844
- message: "Mock scoped recipe execution successful"
2845
- };
2846
- }
2847
- async getActiveRunsAsync(options) {
2848
- this.log("getActiveRunsAsync called:", options);
2849
- const appIdentifier = this.appId;
2850
- let state = this.mockSimulationStates.get(appIdentifier);
2851
- if (!state) {
2852
- state = await this.initializeSimulationState(appIdentifier);
2853
- }
2854
- return state.activeRuns || [];
2855
- }
2856
- async getAvailableRecipesAsync(options) {
2857
- this.log("getAvailableRecipesAsync called:", options);
2858
- const baseRecipes = [
2859
- { id: "collect_resources", scope: "player", clientViewable: true },
2860
- { id: "upgrade_equipment", scope: "player", clientViewable: true }
2861
- ];
2862
- if (options?.roomId) {
2863
- baseRecipes.push(
2864
- { id: "room_upgrade", scope: "room", clientViewable: true },
2865
- { id: "cooperative_project", scope: "room", clientViewable: true }
2866
- );
3125
+ handleSimulationUpdate(notification) {
3126
+ if (!notification || !notification.subscriptionId) {
3127
+ console.warn("[Venus SDK] Received malformed simulation update");
3128
+ return;
2867
3129
  }
2868
- if (options?.includeActorRecipes && options?.roomId) {
2869
- baseRecipes.push(
2870
- { id: "trade_with_npc", scope: "actor", clientViewable: true },
2871
- { id: "attack_monster", scope: "actor", clientViewable: true }
3130
+ const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
3131
+ if (!callback) {
3132
+ console.warn(
3133
+ "[Venus SDK] Received update for unknown subscription:",
3134
+ notification.subscriptionId
2872
3135
  );
3136
+ return;
2873
3137
  }
2874
- return { success: true, recipes: baseRecipes };
2875
- }
2876
- async getBatchRecipeRequirementsAsync(recipes) {
2877
- this.log("getBatchRecipeRequirementsAsync called:", {
2878
- count: recipes?.length
2879
- });
2880
- const results = (recipes || []).map((q) => ({
2881
- recipeId: q.recipeId,
2882
- entity: q.entity || null,
2883
- amount: q.batchAmount || 1,
2884
- inputs: { cash: "BE:0" },
2885
- canAfford: true,
2886
- disabled: false
2887
- }));
2888
- return { success: true, results };
2889
- }
2890
- async getRecipeRequirementsAsync(recipe) {
2891
- this.log("getRecipeRequirementsAsync called:", recipe);
2892
- return {
2893
- recipeId: recipe.recipeId,
2894
- entity: recipe.entity || null,
2895
- amount: recipe.batchAmount,
2896
- inputs: { cash: "BE:0" },
2897
- canAfford: true,
2898
- disabled: false
2899
- };
2900
- }
2901
- async triggerRecipeChainAsync(recipeId, options) {
2902
- this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
2903
- return {
2904
- success: true,
2905
- message: "Mock recipe chain triggered successfully"
2906
- };
2907
- }
2908
- log(message, ...args) {
2909
- console.log(`[Venus Sim Mock] ${message}`, args);
2910
- }
2911
- async executeRecipe(appIdentifier, recipeId, inputs) {
2912
- this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
2913
- const mockSimulationConfigs = this.mockSimulationConfigs;
2914
- const mockSimulationStates = this.mockSimulationStates;
2915
- let config = mockSimulationConfigs.get(appIdentifier);
2916
- let state = mockSimulationStates.get(appIdentifier);
2917
- if (!config || !state) {
2918
- state = await this.initializeSimulationState(appIdentifier);
2919
- config = mockSimulationConfigs.get(appIdentifier);
2920
- if (!config) {
2921
- throw new Error("Failed to initialize simulation config");
2922
- }
2923
- }
2924
- const recipe = config.recipes?.[recipeId];
2925
- if (!recipe) {
2926
- throw new Error(`Recipe ${recipeId} not found`);
2927
- }
2928
- if (state.disabledRecipes?.includes(recipeId)) {
2929
- throw new Error(`Recipe ${recipeId} is disabled`);
2930
- }
2931
- if (recipe.inputs) {
2932
- for (const [entityId, required] of Object.entries(recipe.inputs)) {
2933
- const available = state.inventory[entityId] || 0;
2934
- if (available < required) {
2935
- throw new Error(
2936
- `Insufficient ${entityId}: required ${required}, available ${available}`
2937
- );
2938
- }
2939
- }
2940
- }
2941
- if (recipe.inputs) {
2942
- for (const [entityId, input] of Object.entries(recipe.inputs)) {
2943
- const inventoryValue = state.inventory[entityId] || 0;
2944
- if (typeof input === "number" && typeof inventoryValue === "number") {
2945
- state.inventory[entityId] = inventoryValue - input;
2946
- }
2947
- }
2948
- }
2949
- if (recipe.beginEffects) {
2950
- this.applyEffects(state, recipe.beginEffects);
2951
- }
2952
- const runId = this.generateRunId();
2953
- const now = Date.now();
2954
- const expiresAt = now + (recipe.duration || 0);
2955
- const run = {
2956
- id: runId,
2957
- recipeId,
2958
- status: "running",
2959
- startTime: now,
2960
- expiresAt,
2961
- inputs: recipe.inputs || {}
2962
- };
2963
- state.activeRuns.push(run);
2964
- if (recipe.duration === 0) {
2965
- this.completeRun(appIdentifier, runId);
2966
- return { status: "completed", runId };
2967
- } else {
2968
- const mockActiveTimers = this.mockActiveTimers;
2969
- const timer = setTimeout(() => {
2970
- this.completeRun(appIdentifier, runId);
2971
- }, recipe.duration);
2972
- const timers = mockActiveTimers.get(appIdentifier) || [];
2973
- timers.push(timer);
2974
- mockActiveTimers.set(appIdentifier, timers);
2975
- return {
2976
- status: "running",
2977
- runId,
2978
- expiresAt: new Date(expiresAt).toISOString()
2979
- };
3138
+ try {
3139
+ callback(notification.updates);
3140
+ } catch (error) {
3141
+ console.error("[Venus SDK] Error in simulation subscription callback", error);
2980
3142
  }
2981
3143
  }
2982
- async initializeSimulationState(appIdentifier) {
2983
- this.log(`Initializing simulation state for ${appIdentifier}`);
2984
- const providedSimulationConfig = this.providedSimulationConfig;
2985
- const mockSimulationConfigs = this.mockSimulationConfigs;
2986
- const mockSimulationStates = this.mockSimulationStates;
2987
- const mockActiveTimers = this.mockActiveTimers;
2988
- const config = providedSimulationConfig || {
2989
- version: "1.0",
2990
- entities: {},
2991
- recipes: {}
2992
- };
2993
- mockSimulationConfigs.set(appIdentifier, config);
2994
- const initialInventory = {};
2995
- if (providedSimulationConfig && config.entities) {
2996
- Object.keys(config.entities).forEach((entityId) => {
2997
- initialInventory[entityId] = 0;
2998
- });
2999
- }
3000
- const state = {
3001
- inventory: initialInventory,
3002
- activeRuns: [],
3003
- disabledRecipes: new Array()
3004
- };
3005
- if (config.recipes) {
3006
- Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
3007
- if (recipe.metadata?.startsDisabled) {
3008
- state.disabledRecipes.push(recipeId);
3009
- }
3010
- });
3011
- }
3012
- mockSimulationStates.set(appIdentifier, state);
3013
- mockActiveTimers.set(appIdentifier, []);
3014
- console.log(
3015
- `[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
3016
- state
3017
- );
3018
- if (config.recipes) {
3019
- Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
3020
- const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
3021
- if (isAutoRestart && recipe.outputs) {
3022
- this.log(`Found auto-restart recipe: ${recipeId}`, {
3023
- topLevelAutoRestart: recipe.autoRestart,
3024
- metadataAutoRestart: recipe.metadata?.autoRestart,
3025
- hasOutputs: !!recipe.outputs,
3026
- duration: recipe.duration
3027
- });
3028
- const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
3029
- if (condition && condition.entity) {
3030
- const currentAmount = initialInventory[condition.entity] || 0;
3031
- if (currentAmount < condition.maxValue) {
3032
- console.log(
3033
- `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
3034
- {
3035
- currentAmount,
3036
- maxValue: condition.maxValue,
3037
- entity: condition.entity
3038
- }
3039
- );
3040
- setTimeout(() => {
3041
- this.executeRecipe(appIdentifier, recipeId, {});
3042
- }, 1e3);
3043
- }
3044
- } else {
3045
- console.log(
3046
- `[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
3047
- );
3048
- setTimeout(() => {
3049
- this.executeRecipe(appIdentifier, recipeId, {});
3050
- }, 1e3);
3051
- }
3052
- }
3053
- });
3054
- }
3055
- return state;
3056
- }
3057
- generateRunId() {
3058
- return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
3059
- }
3060
- completeRun(appIdentifier, runId) {
3061
- this.log(`Completing run ${runId} for ${appIdentifier}`);
3062
- const mockSimulationConfigs = this.mockSimulationConfigs;
3063
- const mockSimulationStates = this.mockSimulationStates;
3064
- const config = mockSimulationConfigs.get(appIdentifier);
3065
- const state = mockSimulationStates.get(appIdentifier);
3066
- if (!config || !state) return;
3067
- const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
3068
- if (runIndex === -1) return;
3069
- const run = state.activeRuns[runIndex];
3070
- const recipe = config.recipes?.[run.recipeId];
3071
- if (!recipe) return;
3072
- const outputs = {};
3073
- const rng = this.createSeededRandom(runId);
3074
- if (recipe.outputs) {
3075
- for (const [entityId, value] of Object.entries(recipe.outputs)) {
3076
- if (typeof value === "number") {
3077
- outputs[entityId] = value;
3078
- } else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
3079
- outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
3080
- }
3081
- }
3082
- }
3083
- for (const [entityId, amount] of Object.entries(outputs)) {
3084
- state.inventory[entityId] = (state.inventory[entityId] || 0) + amount;
3144
+ ensureValidSubscribeOptions(options) {
3145
+ if (typeof options !== "object" || options === null) {
3146
+ throw new Error("Simulation subscribe requires an options object");
3085
3147
  }
3086
- if (recipe.endEffects) {
3087
- this.applyEffects(state, recipe.endEffects);
3148
+ const opts = options;
3149
+ if (typeof opts.onUpdate !== "function") {
3150
+ throw new Error("Simulation subscribe requires an onUpdate callback");
3088
3151
  }
3089
- run.status = "completed";
3090
- run.outputs = outputs;
3091
- state.activeRuns.splice(runIndex, 1);
3092
- const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
3093
- if (isAutoRestart) {
3094
- console.log(
3095
- `[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
3096
- {
3097
- topLevelAutoRestart: recipe.autoRestart,
3098
- metadataAutoRestart: recipe.metadata?.autoRestart,
3099
- hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
3100
- }
3152
+ const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
3153
+ if (!hasFilter) {
3154
+ throw new Error(
3155
+ "Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
3101
3156
  );
3102
- const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
3103
- if (condition) {
3104
- const currentAmount = state.inventory[condition.entity] || 0;
3105
- if (currentAmount < condition.maxValue) {
3106
- console.log(
3107
- `[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
3108
- {
3109
- currentAmount,
3110
- maxValue: condition.maxValue,
3111
- entity: condition.entity
3112
- }
3113
- );
3114
- setTimeout(() => {
3115
- this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3116
- }, 1e3);
3117
- }
3118
- } else {
3119
- console.log(
3120
- `[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
3121
- );
3122
- setTimeout(() => {
3123
- this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
3124
- }, 1e3);
3125
- }
3126
- }
3127
- console.log(
3128
- `[Venus Simulation Mock] Completed run ${runId}, outputs:`,
3129
- outputs
3130
- );
3131
- }
3132
- createSeededRandom(seed) {
3133
- let hash = 0;
3134
- for (let i = 0; i < seed.length; i++) {
3135
- const char = seed.charCodeAt(i);
3136
- hash = (hash << 5) - hash + char;
3137
- hash = hash & hash;
3138
- }
3139
- return () => {
3140
- hash = (hash * 9301 + 49297) % 233280;
3141
- return hash / 233280;
3142
- };
3143
- }
3144
- applyEffects(state, effects) {
3145
- if (!effects || !Array.isArray(effects)) return;
3146
- for (const effect of effects) {
3147
- switch (effect.type) {
3148
- case "set":
3149
- state.inventory[effect.target] = effect.value;
3150
- console.log(
3151
- `[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
3152
- );
3153
- break;
3154
- case "add":
3155
- state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
3156
- console.log(
3157
- `[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
3158
- );
3159
- break;
3160
- case "multiply":
3161
- state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
3162
- console.log(
3163
- `[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
3164
- );
3165
- break;
3166
- case "min":
3167
- state.inventory[effect.target] = Math.max(
3168
- state.inventory[effect.target] || 0,
3169
- effect.value
3170
- );
3171
- console.log(
3172
- `[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
3173
- );
3174
- break;
3175
- case "max":
3176
- state.inventory[effect.target] = Math.min(
3177
- state.inventory[effect.target] || 0,
3178
- effect.value
3179
- );
3180
- console.log(
3181
- `[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
3182
- );
3183
- break;
3184
- case "enable_recipe":
3185
- if (state.disabledRecipes?.includes(effect.target)) {
3186
- state.disabledRecipes = state.disabledRecipes.filter(
3187
- (r) => r !== effect.target
3188
- );
3189
- console.log(
3190
- `[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
3191
- );
3192
- }
3193
- break;
3194
- case "disable_recipe":
3195
- if (!state.disabledRecipes) state.disabledRecipes = [];
3196
- if (!state.disabledRecipes.includes(effect.target)) {
3197
- state.disabledRecipes.push(effect.target);
3198
- console.log(
3199
- `[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
3200
- );
3201
- }
3202
- break;
3203
- case "trigger_recipe":
3204
- console.log(
3205
- `[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
3206
- );
3207
- break;
3208
- default:
3209
- console.warn(
3210
- `[Venus Simulation Mock] Unknown effect type: ${effect.type}`
3211
- );
3212
- }
3213
3157
  }
3214
3158
  }
3215
- async getConfigAsync() {
3216
- console.log("[Venus Simulation Mock] getConfigAsync called");
3217
- const appIdentifier = this.appId;
3218
- const mockSimulationConfigs = this.mockSimulationConfigs;
3219
- const config = mockSimulationConfigs.get(appIdentifier) || {
3220
- version: "1.0",
3221
- entities: {},
3222
- recipes: {}
3223
- };
3224
- return config;
3225
- }
3226
- async getStateAsync(roomId) {
3227
- this.log("getStateAsync called:", roomId);
3228
- const appIdentifier = this.appId;
3229
- const mockSimulationStates = this.mockSimulationStates;
3230
- let state = mockSimulationStates.get(appIdentifier);
3231
- if (!state) {
3232
- state = await this.initializeSimulationState(appIdentifier);
3233
- }
3234
- const mockSimulationConfigs = this.mockSimulationConfigs;
3235
- return {
3236
- ...state,
3237
- roomId,
3238
- configuration: mockSimulationConfigs.get(appIdentifier)
3239
- };
3240
- }
3241
- async assignItemToSlotAsync(containerId, slotId, itemId) {
3242
- this.log("assignItemToSlotAsync called:", {
3243
- containerId,
3244
- slotId,
3245
- itemId
3246
- });
3247
- return { success: true, message: "Mock assignment successful" };
3248
- }
3249
- async removeItemFromSlotAsync(containerId, slotId) {
3250
- this.log("removeItemFromSlotAsync called:", {
3251
- containerId,
3252
- slotId
3253
- });
3254
- return { success: true, message: "Mock removal successful" };
3255
- }
3256
3159
  };
3257
3160
 
3258
3161
  // src/simulation/index.ts
3259
3162
  function initializeSimulation(venusApi, host) {
3260
- console.log("[Venus SDK] Initializing new Simulation Api");
3261
3163
  venusApi.simulation = {
3262
3164
  isEnabled: () => true
3263
3165
  };
3264
3166
  venusApi.simulation.getConfigAsync = () => {
3265
3167
  return host.simulation.getConfigAsync();
3266
3168
  };
3267
- venusApi.simulation.getStateAsync = (options) => {
3268
- return host.simulation.getStateAsync(options?.roomId);
3169
+ venusApi.simulation.getStateAsync = (roomId) => {
3170
+ return host.simulation.getStateAsync(roomId);
3269
3171
  };
3270
3172
  venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
3271
3173
  return host.simulation.executeRecipeAsync(recipeId, inputs, options);
@@ -3276,31 +3178,17 @@ function initializeSimulation(venusApi, host) {
3276
3178
  venusApi.simulation.collectRecipeAsync = (runId) => {
3277
3179
  return host.simulation.collectRecipeAsync(runId);
3278
3180
  };
3279
- venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, roomId, options) => {
3280
- return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, {
3281
- roomId,
3282
- ...options
3283
- });
3181
+ venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
3182
+ return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
3284
3183
  };
3285
- venusApi.simulation.triggerRecipeChainAsync = (recipeId, context, roomId) => {
3286
- return host.simulation.triggerRecipeChainAsync(recipeId, {
3287
- context,
3288
- roomId
3289
- });
3184
+ venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
3185
+ return host.simulation.triggerRecipeChainAsync(recipeId, options);
3290
3186
  };
3291
- venusApi.simulation.getAvailableRecipesAsync = async (roomId, includeActorRecipes) => {
3292
- const result = await host.simulation.getAvailableRecipesAsync({
3293
- roomId,
3294
- includeActorRecipes
3295
- });
3296
- return result.recipes;
3187
+ venusApi.simulation.getAvailableRecipesAsync = async (options) => {
3188
+ return host.simulation.getAvailableRecipesAsync(options);
3297
3189
  };
3298
- venusApi.simulation.getRecipeRequirementsAsync = (recipeId, entity, amount) => {
3299
- return host.simulation.getRecipeRequirementsAsync({
3300
- recipeId,
3301
- entity,
3302
- batchAmount: amount
3303
- });
3190
+ venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
3191
+ return host.simulation.getRecipeRequirementsAsync(recipe);
3304
3192
  };
3305
3193
  venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
3306
3194
  return host.simulation.getBatchRecipeRequirementsAsync(recipes);
@@ -3343,9 +3231,6 @@ function initializeSimulation(venusApi, host) {
3343
3231
  itemId
3344
3232
  );
3345
3233
  };
3346
- venusApi.simulation.sumContributions = (contributions) => {
3347
- return host.simulation.sumContributions(contributions);
3348
- };
3349
3234
  }
3350
3235
 
3351
3236
  // src/time/utils.ts
@@ -3460,7 +3345,6 @@ var MockTimeApi = class {
3460
3345
  maximumFractionDigits: options?.maximumFractionDigits || 2,
3461
3346
  ...options
3462
3347
  };
3463
- console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
3464
3348
  return value.toLocaleString(locale, numberOptions);
3465
3349
  }
3466
3350
  formatTime(timestamp, options) {
@@ -3472,13 +3356,9 @@ var MockTimeApi = class {
3472
3356
  hour12: options.hour12 !== void 0 ? options.hour12 : true,
3473
3357
  ...options
3474
3358
  };
3475
- console.log(
3476
- `[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
3477
- );
3478
3359
  return date.toLocaleString(locale, dateTimeOptions);
3479
3360
  }
3480
3361
  async getFutureTimeAsync(options) {
3481
- console.log("[Venus Mock] Getting future time with options:", options);
3482
3362
  const timeInfo = await this.requestTimeAsync();
3483
3363
  const serverTime = new Date(timeInfo.serverTime);
3484
3364
  const result = new Date(serverTime);
@@ -3523,7 +3403,6 @@ var MockTimeApi = class {
3523
3403
  return result.getTime();
3524
3404
  }
3525
3405
  async requestTimeAsync() {
3526
- console.log("[Venus Mock] Requesting time");
3527
3406
  await createMockDelay(MOCK_DELAYS.short);
3528
3407
  const venusApi = this.venusApi;
3529
3408
  const mockOffset = venusApi._mock.serverTimeOffset || 2500;
@@ -3537,11 +3416,6 @@ var MockTimeApi = class {
3537
3416
  formattedTime: new Date(localTime).toISOString(),
3538
3417
  locale: venusApi._mock.user?.locale || "en-US"
3539
3418
  };
3540
- console.log("[Venus Mock] Time response:", {
3541
- serverTime: new Date(timeInfo.serverTime).toISOString(),
3542
- localTime: new Date(timeInfo.localTime).toISOString(),
3543
- timezoneOffset: timeInfo.timezoneOffset
3544
- });
3545
3419
  return timeInfo;
3546
3420
  }
3547
3421
  };
@@ -3563,7 +3437,7 @@ function initializeTime(venusApi, host) {
3563
3437
  }
3564
3438
 
3565
3439
  // src/version.ts
3566
- var SDK_VERSION = "3.1.0-beta.0";
3440
+ var SDK_VERSION = "3.1.1";
3567
3441
 
3568
3442
  // src/shared-assets/consts.ts
3569
3443
  var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
@@ -4238,82 +4112,6 @@ function initializePreloader(venusApi, host) {
4238
4112
  venusApi.preloader = host.preloader;
4239
4113
  }
4240
4114
 
4241
- // src/post/MockPostApi.ts
4242
- var MockPostApi = class {
4243
- constructor(venusApi) {
4244
- __publicField(this, "venusApi");
4245
- this.venusApi = venusApi;
4246
- }
4247
- async getPostInfo() {
4248
- const venusApi = this.venusApi;
4249
- await createMockDelay(MOCK_DELAYS.short);
4250
- return venusApi._mock.currentPostInteractions;
4251
- }
4252
- async openCommentsAsync() {
4253
- await createMockDelay(MOCK_DELAYS.short);
4254
- return {
4255
- opened: true,
4256
- commentsCount: 0
4257
- };
4258
- }
4259
- async toggleFollowAsync() {
4260
- const venusApi = this.venusApi;
4261
- console.log("[Venus Mock] *Toggling follow status");
4262
- await createMockDelay(MOCK_DELAYS.short);
4263
- venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
4264
- const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
4265
- return {
4266
- isFollowing,
4267
- action: isFollowing ? "followed" : "unfollowed"
4268
- };
4269
- }
4270
- async toggleLikeAsync() {
4271
- const venusApi = this.venusApi;
4272
- await createMockDelay(MOCK_DELAYS.short);
4273
- venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
4274
- const isLiked = venusApi._mock.currentPostInteractions.isLiked;
4275
- if (isLiked) {
4276
- venusApi._mock.currentPostInteractions.likesCount++;
4277
- } else {
4278
- venusApi._mock.currentPostInteractions.likesCount = Math.max(
4279
- 0,
4280
- venusApi._mock.currentPostInteractions.likesCount - 1
4281
- );
4282
- }
4283
- return {
4284
- isLiked,
4285
- likesCount: venusApi._mock.currentPostInteractions.likesCount,
4286
- action: isLiked ? "liked" : "unliked"
4287
- };
4288
- }
4289
- };
4290
-
4291
- // src/post/RpcPostApi.ts
4292
- var RpcPostApi = class {
4293
- constructor(rpcClient) {
4294
- __publicField(this, "rpcClient");
4295
- this.rpcClient = rpcClient;
4296
- }
4297
- getPostInfo() {
4298
- return this.rpcClient.call("H5_GET_POST_INTERACTIONS" /* GET_POST_INTERACTIONS */, {});
4299
- }
4300
- openCommentsAsync() {
4301
- return this.rpcClient.call("H5_OPEN_COMMENTS" /* OPEN_COMMENTS */, {});
4302
- }
4303
- toggleFollowAsync() {
4304
- return this.rpcClient.call(
4305
- "H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
4306
- {}
4307
- );
4308
- }
4309
- toggleLikeAsync() {
4310
- return this.rpcClient.call("H5_TOGGLE_LIKE" /* TOGGLE_LIKE */, {});
4311
- }
4312
- };
4313
-
4314
- // src/MockHost.ts
4315
- init_rooms();
4316
-
4317
4115
  // src/social/MockSocialApi.ts
4318
4116
  var MOCK_QR_CODE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
4319
4117
  var MockSocialApi = class {
@@ -4350,44 +4148,116 @@ var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when ru
4350
4148
  function createUnavailableRoomsApi() {
4351
4149
  const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
4352
4150
  return {
4353
- async createRoom() {
4151
+ async createRoomAsync() {
4354
4152
  throw roomsUnavailableError();
4355
4153
  },
4356
- async joinOrCreateRoom() {
4154
+ async joinOrCreateRoomAsync() {
4357
4155
  throw roomsUnavailableError();
4358
4156
  },
4359
- async getUserRooms() {
4157
+ async joinRoomByCodeAsync() {
4360
4158
  throw roomsUnavailableError();
4361
4159
  },
4362
- async joinRoomByCode() {
4160
+ async getUserRoomsAsync() {
4363
4161
  throw roomsUnavailableError();
4364
4162
  },
4365
- subscribe() {
4163
+ async subscribeAsync() {
4366
4164
  throw roomsUnavailableError();
4367
4165
  },
4368
- async updateData() {
4166
+ async updateRoomDataAsync() {
4369
4167
  throw roomsUnavailableError();
4370
4168
  },
4371
- async getData() {
4169
+ async getRoomDataAsync() {
4372
4170
  throw roomsUnavailableError();
4373
4171
  },
4374
- async sendMessage() {
4172
+ async sendRoomMessageAsync() {
4375
4173
  throw roomsUnavailableError();
4376
4174
  },
4377
- async leave() {
4175
+ async leaveRoomAsync() {
4378
4176
  throw roomsUnavailableError();
4379
4177
  },
4380
- async startGame() {
4178
+ async startRoomGameAsync() {
4381
4179
  throw roomsUnavailableError();
4382
4180
  },
4383
- async proposeMove() {
4181
+ async proposeMoveAsync() {
4384
4182
  throw roomsUnavailableError();
4385
4183
  },
4386
- async validateMove() {
4184
+ async validateMoveAsync() {
4387
4185
  throw roomsUnavailableError();
4388
4186
  }
4389
4187
  };
4390
4188
  }
4189
+ var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
4190
+ function createUnavailableSimulationApi() {
4191
+ const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
4192
+ return {
4193
+ isEnabled() {
4194
+ return false;
4195
+ },
4196
+ async getStateAsync() {
4197
+ throw simulationUnavailableError();
4198
+ },
4199
+ async getConfigAsync() {
4200
+ throw simulationUnavailableError();
4201
+ },
4202
+ async executeRecipeAsync() {
4203
+ throw simulationUnavailableError();
4204
+ },
4205
+ async getActiveRunsAsync() {
4206
+ throw simulationUnavailableError();
4207
+ },
4208
+ async collectRecipeAsync() {
4209
+ throw simulationUnavailableError();
4210
+ },
4211
+ async executeScopedRecipeAsync() {
4212
+ throw simulationUnavailableError();
4213
+ },
4214
+ async triggerRecipeChainAsync() {
4215
+ throw simulationUnavailableError();
4216
+ },
4217
+ async getAvailableRecipesAsync() {
4218
+ throw simulationUnavailableError();
4219
+ },
4220
+ async getRecipeRequirementsAsync() {
4221
+ throw simulationUnavailableError();
4222
+ },
4223
+ async getBatchRecipeRequirementsAsync() {
4224
+ throw simulationUnavailableError();
4225
+ },
4226
+ async resolveFieldValueAsync() {
4227
+ throw simulationUnavailableError();
4228
+ },
4229
+ async getEntityMetadataAsync() {
4230
+ throw simulationUnavailableError();
4231
+ },
4232
+ async getSlotContainersAsync() {
4233
+ throw simulationUnavailableError();
4234
+ },
4235
+ async getSlotAssignmentsAsync() {
4236
+ throw simulationUnavailableError();
4237
+ },
4238
+ async assignItemToSlotAsync() {
4239
+ throw simulationUnavailableError();
4240
+ },
4241
+ async removeItemFromSlotAsync() {
4242
+ throw simulationUnavailableError();
4243
+ },
4244
+ async getAvailableItemsAsync() {
4245
+ throw simulationUnavailableError();
4246
+ },
4247
+ async calculatePowerPreviewAsync() {
4248
+ throw simulationUnavailableError();
4249
+ },
4250
+ async validateSlotAssignmentAsync() {
4251
+ throw simulationUnavailableError();
4252
+ },
4253
+ async executeBatchOperationsAsync() {
4254
+ throw simulationUnavailableError();
4255
+ },
4256
+ async subscribeAsync() {
4257
+ throw simulationUnavailableError();
4258
+ }
4259
+ };
4260
+ }
4391
4261
  var MockHost = class {
4392
4262
  constructor(venusApi) {
4393
4263
  __publicField(this, "ads");
@@ -4400,9 +4270,9 @@ var MockHost = class {
4400
4270
  __publicField(this, "notifications");
4401
4271
  __publicField(this, "popups");
4402
4272
  __publicField(this, "profile");
4273
+ __publicField(this, "system");
4403
4274
  __publicField(this, "cdn");
4404
4275
  __publicField(this, "time");
4405
- __publicField(this, "post");
4406
4276
  __publicField(this, "ai");
4407
4277
  __publicField(this, "haptics");
4408
4278
  __publicField(this, "features");
@@ -4434,15 +4304,17 @@ var MockHost = class {
4434
4304
  this.navigation = new MockNavigationApi(venusApi);
4435
4305
  this.notifications = new MockNotificationsApi(venusApi);
4436
4306
  this.popups = new MockPopupsApi(this._overlay);
4437
- this.profile = new MockProfileApi();
4438
- this.cdn = new MockCdnApi();
4307
+ this.profile = new MockProfileApi(venusApi);
4308
+ const deviceApi = new MockDeviceApi(venusApi);
4309
+ const environmentApi = new MockEnvironmentApi(venusApi);
4310
+ this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
4311
+ this.cdn = new MockCdnApi(venusApi);
4439
4312
  this.time = new MockTimeApi(venusApi);
4440
- this.post = new MockPostApi(venusApi);
4441
4313
  this.ai = new MockAiApi();
4442
4314
  this.haptics = new MockHapticsApi(venusApi);
4443
4315
  this.features = new MockFeaturesApi();
4444
4316
  this.lifecycle = this._mockLifecyclesApi;
4445
- this.simulation = new MockSimulationApi();
4317
+ this.simulation = createUnavailableSimulationApi();
4446
4318
  this.rooms = createUnavailableRoomsApi();
4447
4319
  this.logging = new MockLoggingApi();
4448
4320
  this.iap = new MockIapApi();
@@ -4458,40 +4330,17 @@ var MockHost = class {
4458
4330
  }
4459
4331
  initialize(options) {
4460
4332
  this._isInitialized = true;
4461
- const controls = this.updateUiControls();
4333
+ this.venusApi._profileData = this.profile.getCurrentProfile();
4334
+ this.venusApi._deviceData = this.system.getDevice();
4335
+ this.venusApi._environmentData = this.system.getEnvironment();
4336
+ this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
4337
+ this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
4462
4338
  return Promise.resolve({
4463
4339
  initializeAsleep: false,
4464
- hudInsets: {
4465
- top: controls.feedHeader.height,
4466
- bottom: 0,
4467
- left: 0,
4468
- right: 0
4469
- }
4340
+ safeArea: this.venusApi._safeAreaData
4470
4341
  });
4471
4342
  }
4472
- updateUiControls() {
4473
- const controls = {
4474
- closeButton: { x: 16, y: 16, width: 32, height: 32 },
4475
- menuButton: {
4476
- x: window.innerWidth - 48,
4477
- y: 16,
4478
- width: 32,
4479
- height: 32
4480
- },
4481
- feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
4482
- playButton: {
4483
- x: 0,
4484
- y: window.innerHeight - 60,
4485
- width: window.innerWidth,
4486
- height: 60
4487
- }
4488
- };
4489
- return controls;
4490
- }
4491
4343
  createOverlay() {
4492
- const venusApi = this.venusApi;
4493
- venusApi.config.ui.controls = this.updateUiControls();
4494
- const uiControls = venusApi.config.ui.controls;
4495
4344
  const overlayContainer = document.createElement("div");
4496
4345
  overlayContainer.id = "venus-mock-overlay";
4497
4346
  overlayContainer.style.cssText = `
@@ -4507,7 +4356,7 @@ var MockHost = class {
4507
4356
  const menuButton = this.createOverlayButton(
4508
4357
  "close",
4509
4358
  "Menu",
4510
- uiControls.menuButton,
4359
+ { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
4511
4360
  () => {
4512
4361
  this.handleMenuButtonClicked();
4513
4362
  },
@@ -4736,17 +4585,13 @@ var MockHost = class {
4736
4585
  return button;
4737
4586
  }
4738
4587
  updateOverlayLayout() {
4739
- const venusApi = this.venusApi;
4740
4588
  const overlay = this._overlay;
4741
- venusApi.config.ui.controls = this.updateUiControls();
4742
- const uiControls = venusApi.config.ui.controls;
4743
4589
  const menuBtn = overlay.elements.menuButton;
4744
- const menuPos = uiControls.menuButton;
4745
- menuBtn.style.left = `${menuPos.x}px`;
4746
- menuBtn.style.top = `${menuPos.y}px`;
4747
- menuBtn.style.width = `${menuPos.width}px`;
4748
- menuBtn.style.minWidth = `${menuPos.width}px`;
4749
- menuBtn.style.height = `${menuPos.height}px`;
4590
+ menuBtn.style.left = `${window.innerWidth - 48}px`;
4591
+ menuBtn.style.top = "16px";
4592
+ menuBtn.style.width = "32px";
4593
+ menuBtn.style.minWidth = "32px";
4594
+ menuBtn.style.height = "32px";
4750
4595
  }
4751
4596
  triggerLifecycleEvent(name) {
4752
4597
  console.log("Trigger Lifecycle Event: ", name);
@@ -4975,6 +4820,16 @@ var VenusTransport = class {
4975
4820
  this.isProcessingMessage = false;
4976
4821
  return;
4977
4822
  }
4823
+ if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
4824
+ const notification = {
4825
+ type: "rpc-notification",
4826
+ id: message.type,
4827
+ payload: message.data
4828
+ };
4829
+ this.handleNotification(notification);
4830
+ this.isProcessingMessage = false;
4831
+ return;
4832
+ }
4978
4833
  const requestId = messageData.requestId;
4979
4834
  if (!requestId) {
4980
4835
  this.logWarn("No requestId. Ignoring message...");
@@ -5075,358 +4930,70 @@ var VenusTransport = class {
5075
4930
  this.isStarted = true;
5076
4931
  window.addEventListener("message", this.messageHandler, true);
5077
4932
  this.logInfo(`Started`);
5078
- }
5079
- stop() {
5080
- if (!this.isStarted) {
5081
- return;
5082
- }
5083
- this.isStarted = false;
5084
- window.removeEventListener("message", this.messageHandler);
5085
- this.logInfo(`Stopped`);
5086
- }
5087
- handleNotification(notification) {
5088
- for (const callback of this.onNotificationCallbacks) {
5089
- callback(notification);
5090
- }
5091
- for (const callback of this.onNotificationCallbacksToRemove) {
5092
- this.removeOnNotificationCallback(callback);
5093
- }
5094
- this.onNotificationCallbacksToRemove.length = 0;
5095
- }
5096
- async handleResponse(response) {
5097
- for (const callback of this.onResponseCallbacks) {
5098
- const consumed = await callback(response);
5099
- if (consumed) {
5100
- break;
5101
- }
5102
- }
5103
- for (const callback of this.onResponseCallbacksToRemove) {
5104
- this.removeOnResponseCallback(callback);
5105
- }
5106
- this.onResponseCallbacksToRemove.length = 0;
5107
- }
5108
- removeOnResponseCallback(callback) {
5109
- this.onResponseCallbacks.splice(
5110
- this.onResponseCallbacks.indexOf(callback),
5111
- 1
5112
- );
5113
- }
5114
- removeOnNotificationCallback(callback) {
5115
- this.onNotificationCallbacks.splice(
5116
- this.onNotificationCallbacks.indexOf(callback),
5117
- 1
5118
- );
5119
- }
5120
- logInfo(message, ...params) {
5121
- console.log(`[Venus Transport] ${message}`, ...params);
5122
- }
5123
- logWarn(message, ...params) {
5124
- console.warn(`[Venus Transport] ${message}`, ...params);
5125
- }
5126
- onVenusMessage(callback) {
5127
- this.onVenusMessageCallbacks.push(callback);
5128
- return {
5129
- unsubscribe: () => {
5130
- this.onVenusMessageCallbacks.splice(
5131
- this.onVenusMessageCallbacks.indexOf(callback),
5132
- 1
5133
- );
5134
- }
5135
- };
5136
- }
5137
- notifyVenusMessageReceived(message) {
5138
- for (const callback of this.onVenusMessageCallbacks) {
5139
- callback(message);
5140
- }
5141
- }
5142
- };
5143
-
5144
- // src/RemoteHost.ts
5145
- init_rooms();
5146
-
5147
- // src/rooms/RpcRoomsApi.ts
5148
- init_VenusRoom();
5149
- var RpcRoomsApi = class {
5150
- constructor(rpcClient) {
5151
- __publicField(this, "rpcClient");
5152
- __publicField(this, "subscriptions");
5153
- __publicField(this, "transportSubscription", null);
5154
- this.rpcClient = rpcClient;
5155
- this.subscriptions = {
5156
- data: {},
5157
- messages: {},
5158
- gameEvents: {},
5159
- allEvents: {}
5160
- };
5161
- }
5162
- /**
5163
- * Get the subscription state for external access (used by setupRoomNotifications)
5164
- */
5165
- getSubscriptions() {
5166
- return this.subscriptions;
5167
- }
5168
- /**
5169
- * Set up room notification routing from the transport
5170
- */
5171
- setupNotifications(transport) {
5172
- const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
5173
- this.transportSubscription = setupRoomNotifications2(
5174
- transport,
5175
- () => this.getSubscriptions()
5176
- );
5177
- }
5178
- /**
5179
- * Clean up subscriptions and resources
5180
- */
5181
- dispose() {
5182
- if (this.transportSubscription) {
5183
- this.transportSubscription.unsubscribe();
5184
- this.transportSubscription = null;
5185
- console.log("[Venus Rooms] Cleaned up room notification subscription");
5186
- }
5187
- }
5188
- async createRoom(options) {
5189
- const response = await this.rpcClient.call(
5190
- "H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
5191
- {
5192
- options
5193
- }
5194
- );
5195
- if (response.success === false) {
5196
- throw new Error(response.error || "Failed to create room");
5197
- }
5198
- const roomData = response.roomData || response;
5199
- const room = new exports.VenusRoom(roomData);
5200
- return room;
5201
- }
5202
- async joinOrCreateRoom(options) {
5203
- const response = await this.rpcClient.call(
5204
- "H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
5205
- {
5206
- options
5207
- }
5208
- );
5209
- if (response.success === false) {
5210
- throw new Error(response.error || "Failed to join or create room");
5211
- }
5212
- const data = response.value || response;
5213
- const room = new exports.VenusRoom(data.roomData);
5214
- return {
5215
- action: data.action,
5216
- room,
5217
- playersJoined: data.playersJoined
5218
- };
5219
- }
5220
- async joinRoomByCode(roomCode) {
5221
- const response = await this.rpcClient.call(
5222
- "H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
5223
- {
5224
- roomCode
5225
- }
5226
- );
5227
- if (response?.success === false) {
5228
- throw new Error(response.error || "Failed to join room by code");
5229
- }
5230
- const roomData = response.roomData || response;
5231
- const room = new exports.VenusRoom(roomData);
5232
- return room;
5233
- }
5234
- // Get user's rooms with optional filtering
5235
- async getUserRooms(includeArchived = false) {
5236
- const response = await this.rpcClient.call(
5237
- "H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
5238
- {
5239
- includeArchived
5240
- }
5241
- );
5242
- if (response?.success === false) {
5243
- throw new Error(response.error || "Failed to get user rooms");
5244
- }
5245
- const rawRooms = response.rooms || [];
5246
- const venusRooms = [];
5247
- for (const roomData of rawRooms) {
5248
- if (!roomData.id) {
5249
- console.warn("getUserRooms: Skipping room with missing ID:", roomData);
5250
- continue;
5251
- }
5252
- try {
5253
- const venusRoom = new exports.VenusRoom(roomData);
5254
- venusRooms.push(venusRoom);
5255
- } catch (error) {
5256
- console.warn(
5257
- "getUserRooms: Failed to create VenusRoom object:",
5258
- error,
5259
- roomData
5260
- );
5261
- }
5262
- }
5263
- return venusRooms;
5264
- }
5265
- async updateData(room, updates, merge = true) {
5266
- const response = await this.rpcClient.call(
5267
- "H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
5268
- {
5269
- roomId: room.id,
5270
- updates,
5271
- merge
5272
- }
5273
- );
5274
- if (response?.success === false) {
5275
- throw new Error(response.error || "Failed to update room data");
5276
- }
5277
- return response.data;
5278
- }
5279
- async getData(room) {
5280
- const response = await this.rpcClient.call(
5281
- "H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
5282
- {
5283
- roomId: room.id
5284
- }
5285
- );
5286
- if (response?.success === false) {
5287
- throw new Error(response.error || "Failed to get room data");
4933
+ }
4934
+ stop() {
4935
+ if (!this.isStarted) {
4936
+ return;
5288
4937
  }
5289
- return response.data;
4938
+ this.isStarted = false;
4939
+ window.removeEventListener("message", this.messageHandler);
4940
+ this.logInfo(`Stopped`);
5290
4941
  }
5291
- async sendMessage(venusRoom, messageData) {
5292
- const response = await this.rpcClient.call(
5293
- "H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
5294
- {
5295
- roomId: venusRoom.id,
5296
- message: messageData
5297
- }
5298
- );
5299
- if (response?.success === false) {
5300
- throw new Error(response.error || "Failed to send message");
4942
+ handleNotification(notification) {
4943
+ for (const callback of this.onNotificationCallbacks) {
4944
+ callback(notification);
5301
4945
  }
5302
- return response.messageId;
4946
+ for (const callback of this.onNotificationCallbacksToRemove) {
4947
+ this.removeOnNotificationCallback(callback);
4948
+ }
4949
+ this.onNotificationCallbacksToRemove.length = 0;
5303
4950
  }
5304
- async leave(room) {
5305
- const response = await this.rpcClient.call(
5306
- "H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
5307
- {
5308
- roomId: room.id
4951
+ async handleResponse(response) {
4952
+ for (const callback of this.onResponseCallbacks) {
4953
+ const consumed = await callback(response);
4954
+ if (consumed) {
4955
+ break;
5309
4956
  }
5310
- );
5311
- if (response?.success === false) {
5312
- throw new Error(response.error || "Failed to leave room");
5313
4957
  }
5314
- return response;
4958
+ for (const callback of this.onResponseCallbacksToRemove) {
4959
+ this.removeOnResponseCallback(callback);
4960
+ }
4961
+ this.onResponseCallbacksToRemove.length = 0;
5315
4962
  }
5316
- async startGame(room, gameConfig = {}, turnOrder = null) {
5317
- const response = await this.rpcClient.call(
5318
- "H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
5319
- {
5320
- roomId: room.id,
5321
- gameConfig,
5322
- turnOrder
5323
- }
4963
+ removeOnResponseCallback(callback) {
4964
+ this.onResponseCallbacks.splice(
4965
+ this.onResponseCallbacks.indexOf(callback),
4966
+ 1
5324
4967
  );
5325
- if (response?.success === false) {
5326
- throw new Error(response.error || "Failed to start game");
5327
- }
5328
- return response.data;
5329
4968
  }
5330
- async proposeMove(room, proposalPayload) {
5331
- const response = await this.rpcClient.call(
5332
- "h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
5333
- {
5334
- roomId: room.id,
5335
- gameSpecificState: proposalPayload.gameSpecificState,
5336
- moveType: proposalPayload.moveType,
5337
- clientContext: proposalPayload.clientContext,
5338
- clientProposalId: proposalPayload.clientProposalId
5339
- }
4969
+ removeOnNotificationCallback(callback) {
4970
+ this.onNotificationCallbacks.splice(
4971
+ this.onNotificationCallbacks.indexOf(callback),
4972
+ 1
5340
4973
  );
5341
- if (response?.success === false) {
5342
- throw new Error(response.error || "Failed to propose move");
5343
- }
5344
- return response.data;
5345
4974
  }
5346
- async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
5347
- console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
5348
- return { success: true, moveId, isValid, reason };
4975
+ logInfo(message, ...params) {
4976
+ console.log(`[Venus Transport] ${message}`, ...params);
5349
4977
  }
5350
- async roomSubscribeToGameEvents(room, callback) {
5351
- "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5352
- if (!this.subscriptions.gameEvents[room.id]) {
5353
- this.subscriptions.gameEvents[room.id] = [];
5354
- }
5355
- this.subscriptions.gameEvents[room.id].push(callback);
4978
+ logWarn(message, ...params) {
4979
+ console.warn(`[Venus Transport] ${message}`, ...params);
5356
4980
  }
5357
- subscribe(room, options = {}) {
5358
- const subscriptionIds = [];
5359
- const roomId = room.id;
5360
- if (options.onData) {
5361
- const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5362
- if (!this.subscriptions.data[roomId]) {
5363
- this.subscriptions.data[roomId] = [];
5364
- }
5365
- this.subscriptions.data[roomId].push(options.onData);
5366
- subscriptionIds.push({
5367
- type: "data",
5368
- id: dataSubId,
5369
- callback: options.onData
5370
- });
5371
- }
5372
- if (options.onMessages) {
5373
- const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5374
- if (!this.subscriptions.messages[roomId]) {
5375
- this.subscriptions.messages[roomId] = [];
5376
- }
5377
- this.subscriptions.messages[roomId].push(options.onMessages);
5378
- subscriptionIds.push({
5379
- type: "messages",
5380
- id: msgSubId,
5381
- callback: options.onMessages
5382
- });
5383
- }
5384
- if (options.onMoves || options.onGameEvents) {
5385
- const handler = options.onMoves || options.onGameEvents;
5386
- if (handler) {
5387
- const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
5388
- if (!this.subscriptions.gameEvents[roomId]) {
5389
- this.subscriptions.gameEvents[roomId] = [];
5390
- }
5391
- this.subscriptions.gameEvents[roomId].push(handler);
5392
- subscriptionIds.push({
5393
- type: "gameEvents",
5394
- id: gameSubId,
5395
- callback: handler
5396
- });
5397
- }
5398
- }
5399
- 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;
5400
- if (needsSubscription) {
5401
- this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
5402
- roomId,
5403
- subscribeToData: !!options.onData,
5404
- subscribeToMessages: !!options.onMessages,
5405
- subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
5406
- }).catch((error) => {
5407
- console.error("Failed to set up room subscription:", error);
5408
- });
5409
- }
5410
- let called = false;
5411
- return () => {
5412
- if (called) return;
5413
- called = true;
5414
- subscriptionIds.forEach((sub) => {
5415
- const bucket = this.subscriptions[sub.type];
5416
- const callbacks = bucket && bucket[roomId] || [];
5417
- const index = callbacks.indexOf(sub.callback);
5418
- if (index > -1) callbacks.splice(index, 1);
5419
- });
5420
- const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
5421
- if (hasNoCallbacks) {
5422
- this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
5423
- roomId
5424
- }).catch((error) => {
5425
- console.error("Failed to clean up room subscription:", error);
5426
- });
4981
+ onVenusMessage(callback) {
4982
+ this.onVenusMessageCallbacks.push(callback);
4983
+ return {
4984
+ unsubscribe: () => {
4985
+ this.onVenusMessageCallbacks.splice(
4986
+ this.onVenusMessageCallbacks.indexOf(callback),
4987
+ 1
4988
+ );
5427
4989
  }
5428
4990
  };
5429
4991
  }
4992
+ notifyVenusMessageReceived(message) {
4993
+ for (const callback of this.onVenusMessageCallbacks) {
4994
+ callback(message);
4995
+ }
4996
+ }
5430
4997
  };
5431
4998
 
5432
4999
  // src/social/RpcSocialApi.ts
@@ -5475,9 +5042,9 @@ var RemoteHost = class {
5475
5042
  __publicField(this, "notifications");
5476
5043
  __publicField(this, "popups");
5477
5044
  __publicField(this, "profile");
5045
+ __publicField(this, "system");
5478
5046
  __publicField(this, "cdn");
5479
5047
  __publicField(this, "time");
5480
- __publicField(this, "post");
5481
5048
  __publicField(this, "ai");
5482
5049
  __publicField(this, "haptics");
5483
5050
  __publicField(this, "features");
@@ -5531,10 +5098,12 @@ var RemoteHost = class {
5531
5098
  this.navigation = new RpcNavigationApi(rpcClient, venusApi);
5532
5099
  this.notifications = new RpcNotificationsApi(rpcClient);
5533
5100
  this.popups = new RpcPopupsApi(rpcClient);
5534
- this.profile = new HostProfileApi();
5101
+ this.profile = new HostProfileApi(venusApi);
5102
+ const deviceApi = new HostDeviceApi(venusApi);
5103
+ const environmentApi = new HostEnvironmentApi(venusApi);
5104
+ this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
5535
5105
  this.cdn = new HostCdnApi(getCdnBaseUrl());
5536
5106
  this.time = new HostTimeApi(rpcClient, venusApi);
5537
- this.post = new RpcPostApi(rpcClient);
5538
5107
  this.ai = new RpcAiApi(rpcClient);
5539
5108
  this.haptics = new RpcHapticsApi(rpcClient);
5540
5109
  this.features = new RpcFeaturesApi(rpcClient);
@@ -5549,7 +5118,6 @@ var RemoteHost = class {
5549
5118
  venusApi.isMock = () => false;
5550
5119
  this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
5551
5120
  initializeRoomsApi(this.venusApi, this);
5552
- console.log("[Venus SDK] Remote host created");
5553
5121
  }
5554
5122
  get isInitialized() {
5555
5123
  return this._isInitialized;
@@ -5568,35 +5136,27 @@ var RemoteHost = class {
5568
5136
  );
5569
5137
  transport.instanceId = response.instanceId;
5570
5138
  this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
5571
- if (response.profile) {
5572
- const profile = response.profile;
5573
- const sanitizedProfile = {
5574
- id: profile.id,
5575
- username: profile.username,
5576
- avatarUrl: profile.avatarUrl ?? null,
5577
- isAnonymous: Boolean(profile.isAnonymous)
5578
- };
5579
- if (typeof window !== "undefined") {
5580
- const globalWindow = window;
5581
- const venus = globalWindow.venus || (globalWindow.venus = {});
5582
- venus.profile = sanitizedProfile;
5583
- if (venus._config) {
5584
- venus._config.profile = sanitizedProfile;
5585
- }
5586
- if (venus.config) {
5587
- venus.config.profile = sanitizedProfile;
5588
- }
5589
- }
5590
- }
5139
+ const profile = response.profile;
5140
+ const sanitizedProfile = {
5141
+ id: profile.id,
5142
+ username: profile.username,
5143
+ avatarUrl: profile.avatarUrl ?? null,
5144
+ isAnonymous: Boolean(profile.isAnonymous)
5145
+ };
5146
+ this.venusApi._profileData = sanitizedProfile;
5147
+ this.venusApi._deviceData = response.device;
5148
+ this.venusApi._environmentData = response.environment;
5149
+ this.venusApi._localeData = response.locale;
5150
+ this.venusApi._languageCodeData = response.languageCode;
5591
5151
  this._isInitialized = true;
5592
- this.venusApi.launchParams = response.launchParams || {};
5152
+ this.venusApi.launchParams = response.launchParams;
5593
5153
  await this.rpcClient.call("READY" /* READY */, {});
5594
- const hudInsets = response.hudInsets;
5595
- if (hudInsets) {
5596
- this.venusApi.config.ui.safeArea = hudInsets;
5154
+ const safeArea = response.safeArea;
5155
+ if (safeArea) {
5156
+ this.venusApi._safeAreaData = safeArea;
5597
5157
  }
5598
5158
  return {
5599
- hudInsets,
5159
+ safeArea,
5600
5160
  initializeAsleep: response.initializeAsleep
5601
5161
  };
5602
5162
  }
@@ -5608,10 +5168,8 @@ var RemoteHost = class {
5608
5168
  // src/Host.ts
5609
5169
  function createHost(venusApi, isMock) {
5610
5170
  if (isMock) {
5611
- console.log("[Venus SDK] Creating Local Host");
5612
5171
  return new MockHost(venusApi);
5613
5172
  } else {
5614
- console.log("[Venus SDK] Creating Remote Host");
5615
5173
  return new RemoteHost(venusApi);
5616
5174
  }
5617
5175
  }
@@ -5624,342 +5182,11 @@ function initializeSocial(venusApi, host) {
5624
5182
  };
5625
5183
  }
5626
5184
 
5627
- // src/webview/webviewLibraryShimSource.ts
5628
- var WEBVIEW_LIBRARY_SHIM_SOURCE = `
5629
- (function () {
5630
- if (typeof window === 'undefined') {
5631
- return;
5632
- }
5633
-
5634
- if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {
5635
- return;
5636
- }
5637
-
5638
- var RESPONSE_TYPE = 'H5_RESPONSE';
5639
- var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET';
5640
- var REQUEST_TIMEOUT_MS = 12000;
5641
- var pendingRequests = new Map();
5642
-
5643
- function ensureConfig() {
5644
- if (!window.__venusLibrariesConfig) {
5645
- window.__venusLibrariesConfig = {
5646
- enabled: false,
5647
- required: [],
5648
- manifest: {},
5649
- cdnBase: ''
5650
- };
5651
- }
5652
- if (!window.__venusLibrariesConfig.manifest) {
5653
- window.__venusLibrariesConfig.manifest = {};
5654
- }
5655
- if (!Array.isArray(window.__venusLibrariesConfig.required)) {
5656
- window.__venusLibrariesConfig.required = [];
5657
- }
5658
- return window.__venusLibrariesConfig;
5659
- }
5660
-
5661
- function ensureExportsRegistry() {
5662
- if (!window.__venusLibraryExports) {
5663
- window.__venusLibraryExports = {};
5664
- }
5665
- return window.__venusLibraryExports;
5666
- }
5667
-
5668
- function hasHostBridge() {
5669
- return !!(window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === 'function');
5670
- }
5671
-
5672
- function registerResponseListeners() {
5673
- if (window.__venusLibraryShim && window.__venusLibraryShim.__listenerRegistered) {
5674
- return;
5675
- }
5676
-
5677
- function handleMessage(event) {
5678
- var payload = parsePayload(event && event.data);
5679
- if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {
5680
- return;
5681
- }
5682
- var requestId = payload.data.requestId;
5683
- if (!requestId || !pendingRequests.has(requestId)) {
5684
- return;
5685
- }
5686
- var pending = pendingRequests.get(requestId);
5687
- pendingRequests.delete(requestId);
5688
- clearTimeout(pending.timeout);
5689
-
5690
- if (payload.data.success === false) {
5691
- pending.reject(new Error(payload.data.error || 'Embedded library load failed'));
5692
- return;
5693
- }
5694
-
5695
- var value = payload.data.value || payload.data;
5696
- if (!value || !value.base64Data) {
5697
- pending.reject(new Error('Embedded library response was missing base64Data'));
5698
- return;
5699
- }
5700
-
5701
- pending.resolve(value.base64Data);
5702
- }
5703
-
5704
- if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
5705
- document.addEventListener('message', handleMessage, false);
5706
- }
5707
- if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
5708
- window.addEventListener('message', handleMessage, false);
5709
- }
5710
-
5711
- if (!window.__venusLibraryShim) {
5712
- window.__venusLibraryShim = {};
5713
- }
5714
- window.__venusLibraryShim.__listenerRegistered = true;
5715
- }
5716
-
5717
- function parsePayload(raw) {
5718
- if (!raw || typeof raw !== 'string') {
5719
- return null;
5720
- }
5721
- try {
5722
- return JSON.parse(raw);
5723
- } catch (error) {
5724
- return null;
5725
- }
5726
- }
5727
-
5728
- function createRequestId(libraryKey) {
5729
- var sanitized = '';
5730
- for (var i = 0; i < libraryKey.length; i++) {
5731
- var c = libraryKey.charAt(i);
5732
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '-' || c === '_') {
5733
- sanitized += c;
5734
- } else {
5735
- sanitized += '_';
5736
- }
5737
- }
5738
- return 'embedded-lib-' + sanitized + '-' + Date.now() + '-' + Math.random().toString(36).slice(2);
5739
- }
5740
-
5741
- function postHostRequest(assetKey, requestId) {
5742
- if (!hasHostBridge()) {
5743
- throw new Error('Host bridge is unavailable');
5744
- }
5745
- var bridge = window.ReactNativeWebView;
5746
- var message = {
5747
- type: REQUEST_TYPE,
5748
- direction: 'H5_TO_APP',
5749
- data: {
5750
- requestId: requestId,
5751
- assetKey: assetKey
5752
- },
5753
- instanceId: (window._venusInitState && window._venusInitState.poolId) || 'unknown',
5754
- timestamp: Date.now()
5755
- };
5756
- bridge.postMessage(JSON.stringify(message));
5757
- }
5758
-
5759
- function loadLibraryViaHost(assetKey, libraryKey) {
5760
- return new Promise(function (resolve, reject) {
5761
- var requestId = createRequestId(libraryKey);
5762
- var timeout = setTimeout(function () {
5763
- pendingRequests.delete(requestId);
5764
- reject(new Error('Timed out loading embedded library: ' + libraryKey));
5765
- }, REQUEST_TIMEOUT_MS);
5766
-
5767
- pendingRequests.set(requestId, { resolve: resolve, reject: reject, timeout: timeout });
5768
-
5769
- try {
5770
- postHostRequest(assetKey, requestId);
5771
- } catch (error) {
5772
- pendingRequests.delete(requestId);
5773
- clearTimeout(timeout);
5774
- reject(error);
5775
- }
5776
- });
5777
- }
5778
-
5779
- function buildCdnUrl(config, entry) {
5780
- var base = config.cdnBase || '';
5781
- if (!base.endsWith('/')) {
5782
- base += '/';
5783
- }
5784
- var path = entry.cdnPath;
5785
- if (path.charAt(0) === '/') {
5786
- path = path.substring(1);
5787
- }
5788
- return base + path;
5789
- }
5790
-
5791
- async function loadLibraryViaCdn(config, entry, libraryKey) {
5792
- if (!config.cdnBase) {
5793
- throw new Error('CDN base URL is not configured');
5794
- }
5795
- var url = buildCdnUrl(config, entry);
5796
- var response = await fetch(url, { credentials: 'omit' });
5797
- if (!response.ok) {
5798
- throw new Error('Failed to fetch embedded library from CDN: ' + libraryKey);
5799
- }
5800
- return await response.text();
5801
- }
5802
-
5803
- function decodeBase64ToUtf8(base64) {
5804
- if (typeof base64 !== 'string') {
5805
- throw new Error('Invalid base64 payload');
5806
- }
5807
-
5808
- if (typeof atob === 'function') {
5809
- var binary = atob(base64);
5810
- if (typeof TextDecoder !== 'undefined') {
5811
- var len = binary.length;
5812
- var bytes = new Uint8Array(len);
5813
- for (var i = 0; i < len; i++) {
5814
- bytes[i] = binary.charCodeAt(i);
5815
- }
5816
- return new TextDecoder('utf-8').decode(bytes);
5817
- }
5818
- return decodeURIComponent(escape(binary));
5819
- }
5820
-
5821
- var bufferCtor = (typeof globalThis !== 'undefined' && globalThis.Buffer) || (typeof window !== 'undefined' && window.Buffer);
5822
- if (bufferCtor) {
5823
- return bufferCtor.from(base64, 'base64').toString('utf-8');
5824
- }
5825
-
5826
- throw new Error('No base64 decoder available');
5827
- }
5828
-
5829
- function evaluateLibrarySource(libraryKey, globalVar, source) {
5830
- var registry = ensureExportsRegistry();
5831
- if (!source) {
5832
- throw new Error('Embedded library source was empty for ' + libraryKey);
5833
- }
5834
-
5835
- var previousValue = window[globalVar];
5836
- try {
5837
- var executor = new Function(source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js');
5838
- executor.call(window);
5839
- } catch (error) {
5840
- throw new Error('Failed to evaluate embedded library ' + libraryKey + ': ' + (error && error.message ? error.message : error));
5841
- }
5842
-
5843
- var exported = window[globalVar] || previousValue;
5844
- if (!exported) {
5845
- throw new Error('Embedded library ' + libraryKey + ' did not register ' + globalVar);
5846
- }
5847
-
5848
- registry[libraryKey] = exported;
5849
- return exported;
5850
- }
5851
-
5852
- async function ensureLibraryLoaded(config, libraryKey) {
5853
- var registry = ensureExportsRegistry();
5854
- if (registry[libraryKey]) {
5855
- return registry[libraryKey];
5856
- }
5857
-
5858
- var entry = config.manifest && config.manifest[libraryKey];
5859
- if (!entry) {
5860
- throw new Error('No manifest entry for embedded library ' + libraryKey);
5861
- }
5862
-
5863
- var source = null;
5864
- if (config.useHost !== false && hasHostBridge()) {
5865
- try {
5866
- var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey);
5867
- source = decodeBase64ToUtf8(base64);
5868
- } catch (error) {
5869
- // Log the RPC error loudly before fallback
5870
- console.error('[Venus Libraries] Failed to load ' + libraryKey + ' from host via RPC:', error);
5871
- console.warn('[Venus Libraries] Falling back to CDN for ' + libraryKey + '. This may indicate an asset packaging issue.');
5872
- }
5873
- }
5874
-
5875
- if (!source) {
5876
- source = await loadLibraryViaCdn(config, entry, libraryKey);
5877
- }
5878
-
5879
- return evaluateLibrarySource(libraryKey, entry.globalVar, source);
5880
- }
5881
-
5882
- async function bootstrap() {
5883
- try {
5884
- registerResponseListeners();
5885
- getBootstrapPromise();
5886
-
5887
- var config = ensureConfig();
5888
-
5889
- if (!config.enabled) {
5890
- if (bootstrapResolve) bootstrapResolve();
5891
- return;
5892
- }
5893
-
5894
- if (!Array.isArray(config.required) || config.required.length === 0) {
5895
- if (bootstrapResolve) bootstrapResolve();
5896
- return;
5897
- }
5898
-
5899
- // Group libraries by load stage for parallel loading within stages
5900
- var librariesByStage = {};
5901
- for (var i = 0; i < config.required.length; i++) {
5902
- var libraryKey = config.required[i];
5903
- var entry = config.manifest[libraryKey];
5904
- var stage = entry.loadStage || 0;
5905
- if (!librariesByStage[stage]) librariesByStage[stage] = [];
5906
- librariesByStage[stage].push(libraryKey);
5907
- }
5908
-
5909
- // Load stages sequentially, libraries within each stage in parallel
5910
- var stages = Object.keys(librariesByStage).sort(function(a, b) {
5911
- return parseInt(a, 10) - parseInt(b, 10);
5912
- });
5913
-
5914
- for (var s = 0; s < stages.length; s++) {
5915
- var stage = stages[s];
5916
- var libs = librariesByStage[stage];
5917
-
5918
- // Load all libraries in this stage in parallel
5919
- var stagePromises = libs.map(function(libraryKey) {
5920
- return ensureLibraryLoaded(config, libraryKey).catch(function(error) {
5921
- console.error('[Venus Libraries] Failed to load library ' + libraryKey, error);
5922
- throw error;
5923
- });
5924
- });
5925
-
5926
- await Promise.all(stagePromises);
5927
- }
5928
-
5929
- if (bootstrapResolve) bootstrapResolve();
5930
- } catch (error) {
5931
- console.error('[Venus Libraries] Bootstrap error', error);
5932
- if (bootstrapReject) bootstrapReject(error);
5933
- throw error;
5934
- }
5935
- }
5185
+ // raw-loader:/Users/pchan/Development/series/venus/venus-sdk/packages/api/src/webview/webviewLibraryShim.js
5186
+ var webviewLibraryShim_default = "/**\r\n * Venus Embedded Libraries WebView Shim\r\n *\r\n * This code is injected into H5 game WebViews BEFORE the game's main script runs.\r\n * It bootstraps the embedded libraries system by:\r\n * 1. Reading window.__venusLibrariesConfig (set by the Vite plugin)\r\n * 2. Loading libraries via RPC (mobile) or CDN (web)\r\n * 3. Registering libraries in window.__venusLibraryExports\r\n * 4. Allowing the game's virtual modules to access them\r\n *\r\n * This shim is NOT imported by H5 games - it's injected by the Venus host via\r\n * injectedJavaScriptBeforeContentLoaded in H5AppPoolRenderer.\r\n */\r\n\r\n;(function () {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {\r\n return\r\n }\r\n\r\n var RESPONSE_TYPE = 'H5_RESPONSE'\r\n var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET'\r\n var REQUEST_TIMEOUT_MS = 12000\r\n var pendingRequests = new Map()\r\n\r\n function ensureConfig() {\r\n if (!window.__venusLibrariesConfig) {\r\n window.__venusLibrariesConfig = {\r\n enabled: false,\r\n required: [],\r\n manifest: {},\r\n cdnBase: '',\r\n }\r\n }\r\n if (!window.__venusLibrariesConfig.manifest) {\r\n window.__venusLibrariesConfig.manifest = {}\r\n }\r\n if (!Array.isArray(window.__venusLibrariesConfig.required)) {\r\n window.__venusLibrariesConfig.required = []\r\n }\r\n return window.__venusLibrariesConfig\r\n }\r\n\r\n function ensureExportsRegistry() {\r\n if (!window.__venusLibraryExports) {\r\n window.__venusLibraryExports = {}\r\n }\r\n return window.__venusLibraryExports\r\n }\r\n\r\n function hasHostBridge() {\r\n return !!(\r\n window.ReactNativeWebView &&\r\n typeof window.ReactNativeWebView.postMessage === 'function'\r\n )\r\n }\r\n\r\n function registerResponseListeners() {\r\n if (\r\n window.__venusLibraryShim &&\r\n window.__venusLibraryShim.__listenerRegistered\r\n ) {\r\n return\r\n }\r\n\r\n function handleMessage(event) {\r\n var payload = parsePayload(event && event.data)\r\n if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {\r\n return\r\n }\r\n var requestId = payload.data.requestId\r\n if (!requestId || !pendingRequests.has(requestId)) {\r\n return\r\n }\r\n var pending = pendingRequests.get(requestId)\r\n pendingRequests.delete(requestId)\r\n clearTimeout(pending.timeout)\r\n\r\n if (payload.data.success === false) {\r\n pending.reject(\r\n new Error(payload.data.error || 'Embedded library load failed'),\r\n )\r\n return\r\n }\r\n\r\n var value = payload.data.value || payload.data\r\n if (!value || !value.base64Data) {\r\n pending.reject(\r\n new Error('Embedded library response was missing base64Data'),\r\n )\r\n return\r\n }\r\n\r\n pending.resolve(value.base64Data)\r\n }\r\n\r\n if (\r\n typeof document !== 'undefined' &&\r\n typeof document.addEventListener === 'function'\r\n ) {\r\n document.addEventListener('message', handleMessage, false)\r\n }\r\n if (\r\n typeof window !== 'undefined' &&\r\n typeof window.addEventListener === 'function'\r\n ) {\r\n window.addEventListener('message', handleMessage, false)\r\n }\r\n\r\n if (!window.__venusLibraryShim) {\r\n window.__venusLibraryShim = {}\r\n }\r\n window.__venusLibraryShim.__listenerRegistered = true\r\n }\r\n\r\n function parsePayload(raw) {\r\n if (!raw || typeof raw !== 'string') {\r\n return null\r\n }\r\n try {\r\n return JSON.parse(raw)\r\n } catch (error) {\r\n return null\r\n }\r\n }\r\n\r\n function createRequestId(libraryKey) {\r\n var sanitized = ''\r\n for (var i = 0; i < libraryKey.length; i++) {\r\n var c = libraryKey.charAt(i)\r\n if (\r\n (c >= 'a' && c <= 'z') ||\r\n (c >= 'A' && c <= 'Z') ||\r\n (c >= '0' && c <= '9') ||\r\n c === '-' ||\r\n c === '_'\r\n ) {\r\n sanitized += c\r\n } else {\r\n sanitized += '_'\r\n }\r\n }\r\n return (\r\n 'embedded-lib-' +\r\n sanitized +\r\n '-' +\r\n Date.now() +\r\n '-' +\r\n Math.random().toString(36).slice(2)\r\n )\r\n }\r\n\r\n function postHostRequest(assetKey, requestId) {\r\n if (!hasHostBridge()) {\r\n throw new Error('Host bridge is unavailable')\r\n }\r\n var bridge = window.ReactNativeWebView\r\n var message = {\r\n type: REQUEST_TYPE,\r\n direction: 'H5_TO_APP',\r\n data: {\r\n requestId: requestId,\r\n assetKey: assetKey,\r\n },\r\n instanceId:\r\n (window._venusInitState && window._venusInitState.poolId) || 'unknown',\r\n timestamp: Date.now(),\r\n }\r\n bridge.postMessage(JSON.stringify(message))\r\n }\r\n\r\n function loadLibraryViaHost(assetKey, libraryKey) {\r\n return new Promise(function (resolve, reject) {\r\n var requestId = createRequestId(libraryKey)\r\n var timeout = setTimeout(function () {\r\n pendingRequests.delete(requestId)\r\n reject(new Error('Timed out loading embedded library: ' + libraryKey))\r\n }, REQUEST_TIMEOUT_MS)\r\n\r\n pendingRequests.set(requestId, {\r\n resolve: resolve,\r\n reject: reject,\r\n timeout: timeout,\r\n })\r\n\r\n try {\r\n postHostRequest(assetKey, requestId)\r\n } catch (error) {\r\n pendingRequests.delete(requestId)\r\n clearTimeout(timeout)\r\n reject(error)\r\n }\r\n })\r\n }\r\n\r\n function buildCdnUrl(config, entry) {\r\n var base = config.cdnBase || ''\r\n if (!base.endsWith('/')) {\r\n base += '/'\r\n }\r\n var path = entry.cdnPath\r\n if (path.charAt(0) === '/') {\r\n path = path.substring(1)\r\n }\r\n return base + path\r\n }\r\n\r\n async function loadLibraryViaCdn(config, entry, libraryKey) {\r\n if (!config.cdnBase) {\r\n throw new Error('CDN base URL is not configured')\r\n }\r\n var url = buildCdnUrl(config, entry)\r\n var response = await fetch(url, { credentials: 'omit' })\r\n if (!response.ok) {\r\n throw new Error(\r\n 'Failed to fetch embedded library from CDN: ' + libraryKey,\r\n )\r\n }\r\n return await response.text()\r\n }\r\n\r\n function decodeBase64ToUtf8(base64) {\r\n if (typeof base64 !== 'string') {\r\n throw new Error('Invalid base64 payload')\r\n }\r\n\r\n if (typeof atob === 'function') {\r\n var binary = atob(base64)\r\n if (typeof TextDecoder !== 'undefined') {\r\n var len = binary.length\r\n var bytes = new Uint8Array(len)\r\n for (var i = 0; i < len; i++) {\r\n bytes[i] = binary.charCodeAt(i)\r\n }\r\n return new TextDecoder('utf-8').decode(bytes)\r\n }\r\n return decodeURIComponent(escape(binary))\r\n }\r\n\r\n var bufferCtor =\r\n (typeof globalThis !== 'undefined' && globalThis.Buffer) ||\r\n (typeof window !== 'undefined' && window.Buffer)\r\n if (bufferCtor) {\r\n return bufferCtor.from(base64, 'base64').toString('utf-8')\r\n }\r\n\r\n throw new Error('No base64 decoder available')\r\n }\r\n\r\n function evaluateLibrarySource(libraryKey, globalVar, source) {\r\n var registry = ensureExportsRegistry()\r\n if (!source) {\r\n throw new Error('Embedded library source was empty for ' + libraryKey)\r\n }\r\n\r\n var previousValue = window[globalVar]\r\n try {\r\n var executor = new Function(\r\n source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js',\r\n )\r\n executor.call(window)\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to evaluate embedded library ' +\r\n libraryKey +\r\n ': ' +\r\n (error && error.message ? error.message : error),\r\n )\r\n }\r\n\r\n var exported = window[globalVar] || previousValue\r\n if (!exported) {\r\n throw new Error(\r\n 'Embedded library ' + libraryKey + ' did not register ' + globalVar,\r\n )\r\n }\r\n\r\n registry[libraryKey] = exported\r\n return exported\r\n }\r\n\r\n async function ensureLibraryLoaded(config, libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n if (registry[libraryKey]) {\r\n return registry[libraryKey]\r\n }\r\n\r\n var entry = config.manifest && config.manifest[libraryKey]\r\n if (!entry) {\r\n throw new Error('No manifest entry for embedded library ' + libraryKey)\r\n }\r\n\r\n var source = null\r\n if (config.useHost !== false && hasHostBridge()) {\r\n try {\r\n var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey)\r\n source = decodeBase64ToUtf8(base64)\r\n } catch (error) {\r\n // Log the RPC error loudly before fallback\r\n console.error(\r\n '[Venus Libraries] Failed to load ' +\r\n libraryKey +\r\n ' from host via RPC:',\r\n error,\r\n )\r\n console.warn(\r\n '[Venus Libraries] Falling back to CDN for ' +\r\n libraryKey +\r\n '. This may indicate an asset packaging issue.',\r\n )\r\n }\r\n }\r\n\r\n if (!source) {\r\n source = await loadLibraryViaCdn(config, entry, libraryKey)\r\n }\r\n\r\n return evaluateLibrarySource(libraryKey, entry.globalVar, source)\r\n }\r\n\r\n async function bootstrap() {\r\n try {\r\n registerResponseListeners()\r\n getBootstrapPromise()\r\n\r\n var config = ensureConfig()\r\n\r\n if (!config.enabled) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n if (!Array.isArray(config.required) || config.required.length === 0) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n // Group libraries by load stage for parallel loading within stages\r\n var librariesByStage = {}\r\n for (var i = 0; i < config.required.length; i++) {\r\n var libraryKey = config.required[i]\r\n var entry = config.manifest[libraryKey]\r\n var stage = entry.loadStage || 0\r\n if (!librariesByStage[stage]) librariesByStage[stage] = []\r\n librariesByStage[stage].push(libraryKey)\r\n }\r\n\r\n // Load stages sequentially, libraries within each stage in parallel\r\n var stages = Object.keys(librariesByStage).sort(function (a, b) {\r\n return parseInt(a, 10) - parseInt(b, 10)\r\n })\r\n\r\n for (var s = 0; s < stages.length; s++) {\r\n var stage = stages[s]\r\n var libs = librariesByStage[stage]\r\n\r\n // Load all libraries in this stage in parallel\r\n var stagePromises = libs.map(function (libraryKey) {\r\n return ensureLibraryLoaded(config, libraryKey).catch(\r\n function (error) {\r\n console.error(\r\n '[Venus Libraries] Failed to load library ' + libraryKey,\r\n error,\r\n )\r\n throw error\r\n },\r\n )\r\n })\r\n\r\n await Promise.all(stagePromises)\r\n }\r\n\r\n if (bootstrapResolve) bootstrapResolve()\r\n } catch (error) {\r\n console.error('[Venus Libraries] Bootstrap error', error)\r\n if (bootstrapReject) bootstrapReject(error)\r\n throw error\r\n }\r\n }\r\n\r\n // Create a promise that resolves when bootstrap completes\r\n var bootstrapPromise = null\r\n var bootstrapResolve = null\r\n var bootstrapReject = null\r\n\r\n function getBootstrapPromise() {\r\n if (!bootstrapPromise) {\r\n bootstrapPromise = new Promise(function (resolve, reject) {\r\n bootstrapResolve = resolve\r\n bootstrapReject = reject\r\n })\r\n }\r\n return bootstrapPromise\r\n }\r\n\r\n window.__venusLibraryShim = {\r\n bootstrap: bootstrap,\r\n ready: getBootstrapPromise,\r\n getExports: function (libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n return registry[libraryKey]\r\n },\r\n __initialized: true,\r\n }\r\n})()\r\n";
5936
5187
 
5937
- // Create a promise that resolves when bootstrap completes
5938
- var bootstrapPromise = null;
5939
- var bootstrapResolve = null;
5940
- var bootstrapReject = null;
5941
-
5942
- function getBootstrapPromise() {
5943
- if (!bootstrapPromise) {
5944
- bootstrapPromise = new Promise(function(resolve, reject) {
5945
- bootstrapResolve = resolve;
5946
- bootstrapReject = reject;
5947
- });
5948
- }
5949
- return bootstrapPromise;
5950
- }
5951
-
5952
- window.__venusLibraryShim = {
5953
- bootstrap: bootstrap,
5954
- ready: getBootstrapPromise,
5955
- getExports: function (libraryKey) {
5956
- var registry = ensureExportsRegistry();
5957
- return registry[libraryKey];
5958
- },
5959
- __initialized: true,
5960
- };
5961
- })();
5962
- `;
5188
+ // src/webview/webviewLibraryShimSource.ts
5189
+ var WEBVIEW_LIBRARY_SHIM_SOURCE = webviewLibraryShim_default;
5963
5190
  function getWebviewLibraryShimSource() {
5964
5191
  return WEBVIEW_LIBRARY_SHIM_SOURCE;
5965
5192
  }
@@ -5971,7 +5198,10 @@ exports.HASH_ALGORITHM_NODE = HASH_ALGORITHM_NODE;
5971
5198
  exports.HASH_ALGORITHM_WEB_CRYPTO = HASH_ALGORITHM_WEB_CRYPTO;
5972
5199
  exports.HapticFeedbackStyle = HapticFeedbackStyle;
5973
5200
  exports.HostCdnApi = HostCdnApi;
5201
+ exports.HostDeviceApi = HostDeviceApi;
5202
+ exports.HostEnvironmentApi = HostEnvironmentApi;
5974
5203
  exports.HostProfileApi = HostProfileApi;
5204
+ exports.HostSystemApi = HostSystemApi;
5975
5205
  exports.HostTimeApi = HostTimeApi;
5976
5206
  exports.MODULE_TO_LIBRARY_SPECIFIERS = MODULE_TO_LIBRARY_SPECIFIERS;
5977
5207
  exports.MockAdsApi = MockAdsApi;
@@ -5979,6 +5209,8 @@ exports.MockAiApi = MockAiApi;
5979
5209
  exports.MockAnalyticsApi = MockAnalyticsApi;
5980
5210
  exports.MockAvatarApi = MockAvatarApi;
5981
5211
  exports.MockCdnApi = MockCdnApi;
5212
+ exports.MockDeviceApi = MockDeviceApi;
5213
+ exports.MockEnvironmentApi = MockEnvironmentApi;
5982
5214
  exports.MockFeaturesApi = MockFeaturesApi;
5983
5215
  exports.MockHapticsApi = MockHapticsApi;
5984
5216
  exports.MockIapApi = MockIapApi;
@@ -5991,9 +5223,9 @@ exports.MockPopupsApi = MockPopupsApi;
5991
5223
  exports.MockPreloaderApi = MockPreloaderApi;
5992
5224
  exports.MockProfileApi = MockProfileApi;
5993
5225
  exports.MockSharedAssetsApi = MockSharedAssetsApi;
5994
- exports.MockSimulationApi = MockSimulationApi;
5995
5226
  exports.MockSocialApi = MockSocialApi;
5996
5227
  exports.MockStorageApi = MockStorageApi;
5228
+ exports.MockSystemApi = MockSystemApi;
5997
5229
  exports.MockTimeApi = MockTimeApi;
5998
5230
  exports.RemoteHost = RemoteHost;
5999
5231
  exports.RpcAdsApi = RpcAdsApi;
@@ -6011,12 +5243,14 @@ exports.RpcNavigationApi = RpcNavigationApi;
6011
5243
  exports.RpcNotificationsApi = RpcNotificationsApi;
6012
5244
  exports.RpcPopupsApi = RpcPopupsApi;
6013
5245
  exports.RpcPreloaderApi = RpcPreloaderApi;
5246
+ exports.RpcRoomsApi = RpcRoomsApi;
6014
5247
  exports.RpcSharedAssetsApi = RpcSharedAssetsApi;
6015
5248
  exports.RpcSimulationApi = RpcSimulationApi;
6016
5249
  exports.RpcSocialApi = RpcSocialApi;
6017
5250
  exports.RpcStorageApi = RpcStorageApi;
6018
5251
  exports.SDK_VERSION = SDK_VERSION;
6019
5252
  exports.VenusMessageId = VenusMessageId;
5253
+ exports.VenusRoom = VenusRoom;
6020
5254
  exports.WEBVIEW_LIBRARY_SHIM_SOURCE = WEBVIEW_LIBRARY_SHIM_SOURCE;
6021
5255
  exports.base64ToArrayBuffer = base64ToArrayBuffer;
6022
5256
  exports.base64ToUtf8 = base64ToUtf8;
@@ -6045,6 +5279,7 @@ exports.initializeSimulation = initializeSimulation;
6045
5279
  exports.initializeSocial = initializeSocial;
6046
5280
  exports.initializeStackNavigation = initializeStackNavigation;
6047
5281
  exports.initializeStorage = initializeStorage;
5282
+ exports.initializeSystem = initializeSystem;
6048
5283
  exports.initializeTime = initializeTime;
6049
5284
  exports.isPacificDaylightTime = isPacificDaylightTime;
6050
5285
  exports.setupRoomNotifications = setupRoomNotifications;