@series-inc/venus-sdk 2.2.1 → 2.4.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.
- package/README.md +716 -716
- package/dist/{AdsApi-BbMHVPYM.d.mts → AdsApi-Cz0XgLM8.d.mts} +162 -3
- package/dist/{AdsApi-BbMHVPYM.d.ts → AdsApi-Cz0XgLM8.d.ts} +162 -3
- package/dist/chunk-KQZIPQLJ.mjs +3352 -0
- package/dist/chunk-KQZIPQLJ.mjs.map +1 -0
- package/dist/{chunk-D4JRVWNC.mjs → chunk-MWUS3A7C.mjs} +2 -2
- package/dist/chunk-MWUS3A7C.mjs.map +1 -0
- package/dist/core-RDMPQV6U.mjs +3 -0
- package/dist/{core-BTXL5C6G.mjs.map → core-RDMPQV6U.mjs.map} +1 -1
- package/dist/index.cjs +235 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +136 -84
- package/dist/index.d.ts +136 -84
- package/dist/index.mjs +2 -2
- package/dist/venus-api/index.cjs +156 -109
- package/dist/venus-api/index.cjs.map +1 -1
- package/dist/venus-api/index.d.mts +12 -12
- package/dist/venus-api/index.d.ts +12 -12
- package/dist/venus-api/index.mjs +47 -97
- package/dist/venus-api/index.mjs.map +1 -1
- package/package.json +51 -47
- package/dist/chunk-AMGTKSDN.mjs +0 -3135
- package/dist/chunk-AMGTKSDN.mjs.map +0 -1
- package/dist/chunk-D4JRVWNC.mjs.map +0 -1
- package/dist/core-BTXL5C6G.mjs +0 -3
|
@@ -0,0 +1,3352 @@
|
|
|
1
|
+
import { __publicField, createMockDelay, MOCK_DELAYS, isWebPlatform } from './chunk-MWUS3A7C.mjs';
|
|
2
|
+
|
|
3
|
+
// src/VenusMessageId.ts
|
|
4
|
+
var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
5
|
+
VenusMessageId2["H5_RESPONSE"] = "H5_RESPONSE";
|
|
6
|
+
VenusMessageId2["IS_REWARDED_AD_READY"] = "H5_IS_REWARDED_AD_READY";
|
|
7
|
+
VenusMessageId2["SHOW_REWARDED_AD"] = "H5_SHOW_REWARDED_AD";
|
|
8
|
+
VenusMessageId2["LOG_ANALYTICS_EVENT"] = "H5_LOG_ANALYTICS_EVENT";
|
|
9
|
+
VenusMessageId2["TRACK_FUNNEL_STEP"] = "H5_TRACK_FUNNEL_STEP";
|
|
10
|
+
VenusMessageId2["DEVICE_CACHE_GET_ITEM"] = "H5_DEVICE_CACHE_GET_ITEM";
|
|
11
|
+
VenusMessageId2["DEVICE_CACHE_SET_ITEM"] = "H5_DEVICE_CACHE_SET_ITEM";
|
|
12
|
+
VenusMessageId2["DEVICE_CACHE_REMOVE_ITEM"] = "H5_DEVICE_CACHE_REMOVE_ITEM";
|
|
13
|
+
VenusMessageId2["DEVICE_CACHE_CLEAR"] = "H5_DEVICE_CACHE_CLEAR";
|
|
14
|
+
VenusMessageId2["DEVICE_CACHE_KEY"] = "H5_DEVICE_CACHE_KEY";
|
|
15
|
+
VenusMessageId2["DEVICE_CACHE_LENGTH"] = "H5_DEVICE_CACHE_LENGTH";
|
|
16
|
+
VenusMessageId2["APP_STORAGE_GET_ITEM"] = "H5_APP_STORAGE_GET_ITEM";
|
|
17
|
+
VenusMessageId2["APP_STORAGE_SET_ITEM"] = "H5_APP_STORAGE_SET_ITEM";
|
|
18
|
+
VenusMessageId2["APP_STORAGE_REMOVE_ITEM"] = "H5_APP_STORAGE_REMOVE_ITEM";
|
|
19
|
+
VenusMessageId2["APP_STORAGE_CLEAR"] = "H5_APP_STORAGE_CLEAR";
|
|
20
|
+
VenusMessageId2["APP_STORAGE_KEY"] = "H5_APP_STORAGE_KEY";
|
|
21
|
+
VenusMessageId2["APP_STORAGE_LENGTH"] = "H5_APP_STORAGE_LENGTH";
|
|
22
|
+
VenusMessageId2["APP_STORAGE_GET_ALL_ITEMS"] = "H5_APP_STORAGE_GET_ALL_ITEMS";
|
|
23
|
+
VenusMessageId2["APP_STORAGE_SET_MULTIPLE_ITEMS"] = "H5_APP_STORAGE_SET_MULTIPLE_ITEMS";
|
|
24
|
+
VenusMessageId2["APP_STORAGE_REMOVE_MULTIPLE_ITEMS"] = "H5_APP_STORAGE_REMOVE_MULTIPLE_ITEMS";
|
|
25
|
+
VenusMessageId2["GLOBAL_STORAGE_GET_ITEM"] = "H5_GLOBAL_STORAGE_GET_ITEM";
|
|
26
|
+
VenusMessageId2["GLOBAL_STORAGE_SET_ITEM"] = "H5_GLOBAL_STORAGE_SET_ITEM";
|
|
27
|
+
VenusMessageId2["GLOBAL_STORAGE_REMOVE_ITEM"] = "H5_GLOBAL_STORAGE_REMOVE_ITEM";
|
|
28
|
+
VenusMessageId2["GLOBAL_STORAGE_CLEAR"] = "H5_GLOBAL_STORAGE_CLEAR";
|
|
29
|
+
VenusMessageId2["GLOBAL_STORAGE_KEY"] = "H5_GLOBAL_STORAGE_KEY";
|
|
30
|
+
VenusMessageId2["GLOBAL_STORAGE_LENGTH"] = "H5_GLOBAL_STORAGE_LENGTH";
|
|
31
|
+
VenusMessageId2["GLOBAL_STORAGE_GET_ALL_ITEMS"] = "H5_GLOBAL_STORAGE_GET_ALL_ITEMS";
|
|
32
|
+
VenusMessageId2["GLOBAL_STORAGE_SET_MULTIPLE_ITEMS"] = "H5_GLOBAL_STORAGE_SET_MULTIPLE_ITEMS";
|
|
33
|
+
VenusMessageId2["GLOBAL_STORAGE_REMOVE_MULTIPLE_ITEMS"] = "H5_GLOBAL_STORAGE_REMOVE_MULTIPLE_ITEMS";
|
|
34
|
+
VenusMessageId2["AVATAR3D_LOAD"] = "H5_AVATAR3D_LOAD";
|
|
35
|
+
VenusMessageId2["AVATAR3D_SAVE"] = "H5_AVATAR3D_SAVE";
|
|
36
|
+
VenusMessageId2["AVATAR3D_DELETE"] = "H5_AVATAR3D_DELETE";
|
|
37
|
+
VenusMessageId2["H5_STACK_PUSH_REQUEST"] = "H5_STACK_PUSH_REQUEST";
|
|
38
|
+
VenusMessageId2["H5_STACK_POP_REQUEST"] = "H5_STACK_POP_REQUEST";
|
|
39
|
+
VenusMessageId2["SCHEDULE_LOCAL_NOTIFICATION"] = "H5_SCHEDULE_LOCAL_NOTIFICATION";
|
|
40
|
+
VenusMessageId2["CANCEL_LOCAL_NOTIFICATION"] = "H5_CANCEL_LOCAL_NOTIFICATION";
|
|
41
|
+
VenusMessageId2["GET_ALL_SCHEDULED_LOCAL_NOTIFICATIONS"] = "H5_GET_ALL_SCHEDULED_LOCAL_NOTIFICATIONS";
|
|
42
|
+
VenusMessageId2["IS_LOCAL_NOTIFICATIONS_ENABLED"] = "H5_IS_LOCAL_NOTIFICATIONS_ENABLED";
|
|
43
|
+
VenusMessageId2["SET_LOCAL_NOTIFICATIONS_ENABLED"] = "H5_SET_LOCAL_NOTIFICATIONS_ENABLED";
|
|
44
|
+
VenusMessageId2["TOAST"] = "H5_TOAST";
|
|
45
|
+
VenusMessageId2["ALERT_DIALOG"] = "H5_ALERT_DIALOG";
|
|
46
|
+
VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
|
|
47
|
+
VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
|
|
48
|
+
VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
|
|
49
|
+
VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
|
|
50
|
+
VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
|
|
51
|
+
VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
|
|
52
|
+
VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
|
|
53
|
+
VenusMessageId2["SHARE_POST"] = "H5_SHARE_POST";
|
|
54
|
+
VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
|
|
55
|
+
VenusMessageId2["AI_GET_AVAILABLE_MODELS"] = "H5_AI_GET_AVAILABLE_MODELS";
|
|
56
|
+
VenusMessageId2["TRIGGER_HAPTIC"] = "H5_TRIGGER_HAPTIC";
|
|
57
|
+
VenusMessageId2["DEBUG"] = "H5_DEBUG";
|
|
58
|
+
VenusMessageId2["H5_IAP_GET_WALLET"] = "H5_IAP_GET_WALLET";
|
|
59
|
+
VenusMessageId2["H5_IAP_SPEND_CURRENCY"] = "H5_IAP_SPEND_CURRENCY";
|
|
60
|
+
VenusMessageId2["SHOW_INTERSTITIAL_AD"] = "H5_SHOW_INTERSTITIAL_AD";
|
|
61
|
+
VenusMessageId2["IAP_SPEND_CURRENCY_COMPLETE"] = "IAP_SPEND_CURRENCY_COMPLETE";
|
|
62
|
+
VenusMessageId2["IAP_WALLET_UPDATE"] = "IAP_WALLET_UPDATE";
|
|
63
|
+
VenusMessageId2["READY"] = "READY";
|
|
64
|
+
VenusMessageId2["INIT_SDK"] = "INITIALIZE_SDK";
|
|
65
|
+
VenusMessageId2["PLAY"] = "PLAY";
|
|
66
|
+
VenusMessageId2["PAUSE"] = "PAUSE";
|
|
67
|
+
VenusMessageId2["RESUME"] = "RESUME";
|
|
68
|
+
VenusMessageId2["SHOWN"] = "SHOWN";
|
|
69
|
+
VenusMessageId2["HIDDEN"] = "HIDDEN";
|
|
70
|
+
VenusMessageId2["QUIT"] = "QUIT";
|
|
71
|
+
VenusMessageId2["CLEANUP"] = "CLEANUP";
|
|
72
|
+
VenusMessageId2["GET_EXPERIMENT"] = "H5_GET_EXPERIMENT";
|
|
73
|
+
VenusMessageId2["GET_FEATURE_FLAG"] = "H5_GET_FEATURE_FLAG";
|
|
74
|
+
VenusMessageId2["GET_FEATURE_GATE"] = "H5_GET_FEATURE_GATE";
|
|
75
|
+
VenusMessageId2["H5_SIMULATION_EXECUTE_RECIPE"] = "H5_SIMULATION_EXECUTE_RECIPE";
|
|
76
|
+
VenusMessageId2["H5_SIMULATION_GET_ACTIVE_RUNS"] = "H5_SIMULATION_GET_ACTIVE_RUNS";
|
|
77
|
+
VenusMessageId2["H5_SIMULATION_COLLECT_RECIPE"] = "H5_SIMULATION_COLLECT_RECIPE";
|
|
78
|
+
VenusMessageId2["H5_SIMULATION_EXECUTE_SCOPED_RECIPE"] = "H5_SIMULATION_EXECUTE_SCOPED_RECIPE";
|
|
79
|
+
VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_RECIPES"] = "H5_SIMULATION_GET_AVAILABLE_RECIPES";
|
|
80
|
+
VenusMessageId2["H5_SIMULATION_GET_RECIPE_REQUIREMENTS"] = "H5_SIMULATION_GET_RECIPE_REQUIREMENTS";
|
|
81
|
+
VenusMessageId2["H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS"] = "H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS";
|
|
82
|
+
VenusMessageId2["H5_SIMULATION_TRIGGER_RECIPE_CHAIN"] = "H5_SIMULATION_TRIGGER_RECIPE_CHAIN";
|
|
83
|
+
VenusMessageId2["H5_SIMULATION_RESOLVE_VALUE"] = "H5_SIMULATION_RESOLVE_VALUE";
|
|
84
|
+
VenusMessageId2["H5_SIMULATION_GET_ENTITY_METADATA"] = "H5_SIMULATION_GET_ENTITY_METADATA";
|
|
85
|
+
VenusMessageId2["H5_SIMULATION_GET_STATE"] = "H5_SIMULATION_GET_STATE";
|
|
86
|
+
VenusMessageId2["H5_SIMULATION_GET_CONFIG"] = "H5_SIMULATION_GET_CONFIG";
|
|
87
|
+
VenusMessageId2["H5_SIMULATION_GET_CONTAINERS"] = "H5_SIMULATION_GET_CONTAINERS";
|
|
88
|
+
VenusMessageId2["H5_SIMULATION_GET_ASSIGNMENTS"] = "H5_SIMULATION_GET_ASSIGNMENTS";
|
|
89
|
+
VenusMessageId2["H5_SIMULATION_ASSIGN_ITEM"] = "H5_SIMULATION_ASSIGN_ITEM";
|
|
90
|
+
VenusMessageId2["H5_SIMULATION_REMOVE_ITEM"] = "H5_SIMULATION_REMOVE_ITEM";
|
|
91
|
+
VenusMessageId2["H5_SIMULATION_CALCULATE_POWER_PREVIEW"] = "H5_SIMULATION_CALCULATE_POWER_PREVIEW";
|
|
92
|
+
VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
|
|
93
|
+
VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
|
|
94
|
+
VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
|
|
95
|
+
VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
|
|
96
|
+
VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
|
|
97
|
+
VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
|
|
98
|
+
VenusMessageId2["H5_ROOM_LEAVE"] = "H5_ROOM_LEAVE";
|
|
99
|
+
VenusMessageId2["H5_ROOM_UPDATE_DATA"] = "H5_ROOM_UPDATE_DATA";
|
|
100
|
+
VenusMessageId2["H5_ROOM_GET_DATA"] = "H5_ROOM_GET_DATA";
|
|
101
|
+
VenusMessageId2["H5_ROOM_SUBSCRIBE"] = "H5_ROOM_SUBSCRIBE";
|
|
102
|
+
VenusMessageId2["H5_ROOM_UNSUBSCRIBE"] = "H5_ROOM_UNSUBSCRIBE";
|
|
103
|
+
VenusMessageId2["H5_ROOM_SEND_MESSAGE"] = "H5_ROOM_SEND_MESSAGE";
|
|
104
|
+
VenusMessageId2["H5_ROOM_GET_MESSAGES"] = "H5_ROOM_GET_MESSAGES";
|
|
105
|
+
VenusMessageId2["H5_ROOM_LIST_ROOMS"] = "H5_ROOM_LIST_ROOMS";
|
|
106
|
+
VenusMessageId2["H5_ROOM_LIST_PUBLIC"] = "H5_ROOM_LIST_PUBLIC";
|
|
107
|
+
VenusMessageId2["H5_ROOM_SEARCH"] = "H5_ROOM_SEARCH";
|
|
108
|
+
VenusMessageId2["H5_ROOM_JOIN_BY_CODE"] = "H5_ROOM_JOIN_BY_CODE";
|
|
109
|
+
VenusMessageId2["H5_ROOM_GET_USER_ROOMS"] = "H5_ROOM_GET_USER_ROOMS";
|
|
110
|
+
VenusMessageId2["H5_ROOM_GET_PLAYERS"] = "H5_ROOM_GET_PLAYERS";
|
|
111
|
+
VenusMessageId2["H5_ROOM_UPDATE_PLAYER_DATA"] = "H5_ROOM_UPDATE_PLAYER_DATA";
|
|
112
|
+
VenusMessageId2["H5_ROOM_START_GAME"] = "H5_ROOM_START_GAME";
|
|
113
|
+
VenusMessageId2["H5_ROOM_PROPOSE_MOVE"] = "h5:room:proposeMove";
|
|
114
|
+
VenusMessageId2["H5_ROOM_END_GAME"] = "H5_ROOM_END_GAME";
|
|
115
|
+
VenusMessageId2["H5_ROOM_ELIMINATE_PLAYER"] = "H5_ROOM_ELIMINATE_PLAYER";
|
|
116
|
+
VenusMessageId2["H5_ROOM_PROMOTE_TO_SPECTATOR"] = "H5_ROOM_PROMOTE_TO_SPECTATOR";
|
|
117
|
+
VenusMessageId2["H5_LOAD_EMBEDDED_ASSET"] = "H5_LOAD_EMBEDDED_ASSET";
|
|
118
|
+
VenusMessageId2["H5_IAP_OPEN_STORE"] = "H5_IAP_OPEN_STORE";
|
|
119
|
+
VenusMessageId2["H5_IAP_GET_CURRENCY_ICON"] = "H5_IAP_GET_CURRENCY_ICON";
|
|
120
|
+
return VenusMessageId2;
|
|
121
|
+
})(VenusMessageId || {});
|
|
122
|
+
|
|
123
|
+
// src/ads/RpcAdsApi.ts
|
|
124
|
+
var RpcAdsApi = class {
|
|
125
|
+
constructor(rpcClient) {
|
|
126
|
+
__publicField(this, "rpcClient");
|
|
127
|
+
this.rpcClient = rpcClient;
|
|
128
|
+
}
|
|
129
|
+
async showInterstitialAd() {
|
|
130
|
+
console.log(`[Venus SDK] [RpcAdsApi] showInterstitialAd`);
|
|
131
|
+
const response = await this.rpcClient.call(
|
|
132
|
+
"H5_SHOW_INTERSTITIAL_AD" /* SHOW_INTERSTITIAL_AD */,
|
|
133
|
+
{},
|
|
134
|
+
-1
|
|
135
|
+
);
|
|
136
|
+
return response.shown;
|
|
137
|
+
}
|
|
138
|
+
async isRewardedAdReadyAsync() {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
async showRewardedAdAsync() {
|
|
142
|
+
console.log("[Venus SDK] [RpcAdsApi] showRewardedAdAsync");
|
|
143
|
+
const result = await this.rpcClient.call(
|
|
144
|
+
"H5_SHOW_REWARDED_AD" /* SHOW_REWARDED_AD */,
|
|
145
|
+
{},
|
|
146
|
+
-1
|
|
147
|
+
);
|
|
148
|
+
const resultAsString = JSON.stringify(result, null, 2);
|
|
149
|
+
console.log(
|
|
150
|
+
`[Venus SDK] [RpcAdsApi] rewarded ad shown with result as JSON:
|
|
151
|
+
${resultAsString}`
|
|
152
|
+
);
|
|
153
|
+
return result.rewardEarned;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// src/ads/MockAdsApi.ts
|
|
158
|
+
var MockAdsApi = class {
|
|
159
|
+
constructor(mockOverlay) {
|
|
160
|
+
__publicField(this, "mockOverlay");
|
|
161
|
+
this.mockOverlay = mockOverlay;
|
|
162
|
+
}
|
|
163
|
+
async isRewardedAdReadyAsync() {
|
|
164
|
+
this.log("[MockAdsApi] isRewardedAdReadyAsync called");
|
|
165
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
async showRewardedAdAsync() {
|
|
169
|
+
this.log("[MockAdsApi] showRewardedAdAsync called");
|
|
170
|
+
await this.mockOverlay.showAdOverlay();
|
|
171
|
+
this.log("[MockAdsApi] Rewarded ad completed");
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
async showInterstitialAd() {
|
|
175
|
+
this.log(`[MockAdsApi] showInterstitialAd`);
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
log(message, ...args) {
|
|
179
|
+
console.log(`[Venus SDK] ${message}`, ...args);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/ads/index.ts
|
|
184
|
+
function initializeAds(venusApiInstance, host) {
|
|
185
|
+
venusApiInstance.isRewardedAdReadyAsync = host.ads.isRewardedAdReadyAsync.bind(host.ads);
|
|
186
|
+
venusApiInstance.showRewardedAdAsync = host.ads.showRewardedAdAsync.bind(
|
|
187
|
+
host.ads
|
|
188
|
+
);
|
|
189
|
+
venusApiInstance.ads = host.ads;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/ai/RpcAiApi.ts
|
|
193
|
+
var RpcAiApi = class {
|
|
194
|
+
constructor(rpcClient) {
|
|
195
|
+
__publicField(this, "rpcClient");
|
|
196
|
+
this.rpcClient = rpcClient;
|
|
197
|
+
}
|
|
198
|
+
async requestChatCompletionAsync(request) {
|
|
199
|
+
const response = await this.rpcClient.call(
|
|
200
|
+
"H5_AI_CHAT_COMPLETION" /* AI_CHAT_COMPLETION */,
|
|
201
|
+
{
|
|
202
|
+
request: (() => {
|
|
203
|
+
const { apiKey, ...requestWithoutApiKey } = request;
|
|
204
|
+
return requestWithoutApiKey;
|
|
205
|
+
})()
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
return response;
|
|
209
|
+
}
|
|
210
|
+
async getAvailableCompletionModels() {
|
|
211
|
+
const response = await this.rpcClient.call(
|
|
212
|
+
"H5_AI_GET_AVAILABLE_MODELS" /* AI_GET_AVAILABLE_MODELS */
|
|
213
|
+
);
|
|
214
|
+
return response;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// src/ai/MockAiApi.ts
|
|
219
|
+
var MockAiApi = class {
|
|
220
|
+
async requestChatCompletionAsync(request) {
|
|
221
|
+
const { apiKey, ...requestBody } = request;
|
|
222
|
+
if (!apiKey) {
|
|
223
|
+
throw new Error("An API key is required for a chat completion request when developing locally.");
|
|
224
|
+
}
|
|
225
|
+
const response = await fetch("https://series.ullm.rho.live/api/v1/completions", {
|
|
226
|
+
method: "POST",
|
|
227
|
+
headers: {
|
|
228
|
+
"Content-Type": "application/json",
|
|
229
|
+
"Authorization": `Bearer ${apiKey}`
|
|
230
|
+
},
|
|
231
|
+
body: JSON.stringify(requestBody)
|
|
232
|
+
});
|
|
233
|
+
if (!response.ok) {
|
|
234
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
235
|
+
}
|
|
236
|
+
const data = await response.json();
|
|
237
|
+
return data;
|
|
238
|
+
}
|
|
239
|
+
async getAvailableCompletionModels() {
|
|
240
|
+
const response = await fetch("https://series.ullm.rho.live/api/v1/models", {
|
|
241
|
+
method: "GET",
|
|
242
|
+
headers: {
|
|
243
|
+
"Content-Type": "application/json"
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
if (!response.ok) {
|
|
247
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
248
|
+
}
|
|
249
|
+
const data = await response.json();
|
|
250
|
+
return data;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/ai/index.ts
|
|
255
|
+
function initializeAi(venusApi, host) {
|
|
256
|
+
venusApi.ai = host.ai;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/analytics/MockAnalyticsApi.ts
|
|
260
|
+
var MockAnalyticsApi = class {
|
|
261
|
+
async recordCustomEvent(eventName, payload) {
|
|
262
|
+
console.log(
|
|
263
|
+
`[Venus Mock] Logging event with ${eventName}, params ${payload}`
|
|
264
|
+
);
|
|
265
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
266
|
+
}
|
|
267
|
+
async trackFunnelStep(stepNumber, stepName, funnelName) {
|
|
268
|
+
console.log(`[Venus Mock] tracking funnel step ${stepName} (step ${stepNumber}) for funnel ${funnelName ?? "game"}`);
|
|
269
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// src/analytics/RpcAnalyticsApi.ts
|
|
274
|
+
var RpcAnalyticsApi = class {
|
|
275
|
+
constructor(rpcClient) {
|
|
276
|
+
__publicField(this, "rpcClient");
|
|
277
|
+
this.rpcClient = rpcClient;
|
|
278
|
+
}
|
|
279
|
+
async recordCustomEvent(eventName, payload) {
|
|
280
|
+
console.log(
|
|
281
|
+
`[Venus SDK] [RpcAnalyticsApi] recordCustomEvent: ${eventName} payload:
|
|
282
|
+
${JSON.stringify(payload, null, 2)}`
|
|
283
|
+
);
|
|
284
|
+
await this.rpcClient.call("H5_LOG_ANALYTICS_EVENT" /* LOG_ANALYTICS_EVENT */, {
|
|
285
|
+
eventName,
|
|
286
|
+
params: payload
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async trackFunnelStep(stepNumber, stepName, funnelName) {
|
|
290
|
+
console.log(
|
|
291
|
+
`[Venus SDK] [RpcAnalyticsApi] trackFunnelStep: stepNumber: ${stepNumber} stepName: ${stepName} funnelName: ${funnelName}`
|
|
292
|
+
);
|
|
293
|
+
await this.rpcClient.call("H5_TRACK_FUNNEL_STEP" /* TRACK_FUNNEL_STEP */, {
|
|
294
|
+
stepNumber,
|
|
295
|
+
stepName,
|
|
296
|
+
funnelName
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// src/analytics/index.ts
|
|
302
|
+
function initializeAnalytics(venusApiInstance, host) {
|
|
303
|
+
venusApiInstance.logCustomEvent = async (options) => {
|
|
304
|
+
await host.analytics.recordCustomEvent(
|
|
305
|
+
options.eventName,
|
|
306
|
+
options.params
|
|
307
|
+
);
|
|
308
|
+
};
|
|
309
|
+
venusApiInstance.analytics = host.analytics;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/avatar3d/MockAvatarApi.ts
|
|
313
|
+
var MockAvatarApi = class {
|
|
314
|
+
constructor(venusApi) {
|
|
315
|
+
__publicField(this, "_venusApi");
|
|
316
|
+
__publicField(this, "cachedAssets", null);
|
|
317
|
+
__publicField(this, "cachedVersion", "");
|
|
318
|
+
this._venusApi = venusApi;
|
|
319
|
+
}
|
|
320
|
+
downloadAssetPaths() {
|
|
321
|
+
console.log("[Venus Mock] Downloading avatar3d asset paths...");
|
|
322
|
+
return this.getAllAssetPaths();
|
|
323
|
+
}
|
|
324
|
+
async deleteAvatar() {
|
|
325
|
+
console.log(`[Venus Mock] Deleting avatar3d config`);
|
|
326
|
+
const venusApi = this._venusApi;
|
|
327
|
+
const currentProfile = venusApi.getCurrentProfile();
|
|
328
|
+
const profileId = currentProfile?.id || "default_profile";
|
|
329
|
+
localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
|
|
330
|
+
console.log(
|
|
331
|
+
`[Venus Mock] Avatar3d config deleted from localStorage for profile: ${profileId}`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
async loadAvatar(avatar3dId) {
|
|
335
|
+
console.log(`[Venus Mock] Loading avatar3d`, { avatar3dId });
|
|
336
|
+
const venusApi = this._venusApi;
|
|
337
|
+
let config;
|
|
338
|
+
if (avatar3dId) {
|
|
339
|
+
console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
|
|
340
|
+
config = await this.selectAvatarConfig(avatar3dId, false);
|
|
341
|
+
} else {
|
|
342
|
+
const currentProfile = venusApi.getCurrentProfile();
|
|
343
|
+
const profileId = currentProfile?.id || "default_profile";
|
|
344
|
+
console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
|
|
345
|
+
console.log(
|
|
346
|
+
"[Venus Mock] Generating fresh avatar config with current CDN URLs"
|
|
347
|
+
);
|
|
348
|
+
if (profileId === "default_profile") {
|
|
349
|
+
config = await this.selectAvatarConfig(null, true);
|
|
350
|
+
} else {
|
|
351
|
+
config = await this.selectAvatarConfig(profileId, false);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return config || null;
|
|
355
|
+
}
|
|
356
|
+
async saveAvatar(config) {
|
|
357
|
+
console.log(`[Venus Mock] Saving avatar3d config:`, config);
|
|
358
|
+
const venusApi = this._venusApi;
|
|
359
|
+
const currentProfile = venusApi.getCurrentProfile();
|
|
360
|
+
const profileId = currentProfile?.id || "default_profile";
|
|
361
|
+
localStorage.setItem(
|
|
362
|
+
`venus-mock-avatar3d-${profileId}`,
|
|
363
|
+
JSON.stringify(config)
|
|
364
|
+
);
|
|
365
|
+
const mockAvatar3dId = `mock_avatar3d_${profileId}_${Date.now()}`;
|
|
366
|
+
console.log(
|
|
367
|
+
`[Venus Mock] Avatar3d config saved to localStorage with mock ID: ${mockAvatar3dId}`
|
|
368
|
+
);
|
|
369
|
+
return mockAvatar3dId;
|
|
370
|
+
}
|
|
371
|
+
downloadManifest() {
|
|
372
|
+
return this.loadAssetsManifest();
|
|
373
|
+
}
|
|
374
|
+
async showEditor(options) {
|
|
375
|
+
console.log(
|
|
376
|
+
`[Venus Mock] showAvatar3dEditorAsync called with options:`,
|
|
377
|
+
options
|
|
378
|
+
);
|
|
379
|
+
if (window.VenusPrototyping) {
|
|
380
|
+
return new Promise((resolve) => {
|
|
381
|
+
window.VenusPrototyping.showAvatarEditorOverlay(options, resolve);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
console.log("[Venus Mock] Simulating avatar editor opening...");
|
|
385
|
+
await createMockDelay(MOCK_DELAYS.medium);
|
|
386
|
+
const mockAvatarConfig = await this.selectAvatarConfig(null, false);
|
|
387
|
+
const userSavedChanges = Math.random() > 0.3;
|
|
388
|
+
console.log(
|
|
389
|
+
"[Venus Mock] Avatar editor simulation complete - user would use requestPopOrQuit() with result data"
|
|
390
|
+
);
|
|
391
|
+
if (userSavedChanges) {
|
|
392
|
+
const mockAvatarId = `mock_avatar_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
393
|
+
return {
|
|
394
|
+
wasChanged: true,
|
|
395
|
+
config: mockAvatarConfig,
|
|
396
|
+
savedAvatarId: mockAvatarId
|
|
397
|
+
};
|
|
398
|
+
} else {
|
|
399
|
+
return {
|
|
400
|
+
wasChanged: false,
|
|
401
|
+
config: null,
|
|
402
|
+
savedAvatarId: null
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
async getAssets() {
|
|
407
|
+
let cachedAssets = this.cachedAssets;
|
|
408
|
+
if (!cachedAssets) {
|
|
409
|
+
this.log("No cached assets found, loading new manifest...");
|
|
410
|
+
cachedAssets = (await this.loadAssetsManifest()).categories;
|
|
411
|
+
}
|
|
412
|
+
return cachedAssets;
|
|
413
|
+
}
|
|
414
|
+
async loadAssetsManifest() {
|
|
415
|
+
this.log("Loading avatar3d assets manifest from CDN...");
|
|
416
|
+
const venusApi = this._venusApi;
|
|
417
|
+
const baseManifestUrl = venusApi.resolveAvatarAssetUrl("assets.json");
|
|
418
|
+
const separator = baseManifestUrl.includes("?") ? "&" : "?";
|
|
419
|
+
const manifestUrl = `${baseManifestUrl}${separator}v=${Date.now()}`;
|
|
420
|
+
console.log("[Venus Mock] Fetching manifest from URL:", manifestUrl);
|
|
421
|
+
try {
|
|
422
|
+
const response = await fetch(manifestUrl, {
|
|
423
|
+
method: "GET",
|
|
424
|
+
headers: {
|
|
425
|
+
Accept: "application/json, text/plain, */*",
|
|
426
|
+
"Content-Type": "application/json"
|
|
427
|
+
},
|
|
428
|
+
mode: "cors",
|
|
429
|
+
cache: "no-cache"
|
|
430
|
+
});
|
|
431
|
+
console.log(
|
|
432
|
+
"[Venus Mock] Fetch response status:",
|
|
433
|
+
response.status,
|
|
434
|
+
response.statusText
|
|
435
|
+
);
|
|
436
|
+
console.log(
|
|
437
|
+
"[Venus Mock] Response headers:",
|
|
438
|
+
Object.fromEntries(response.headers.entries())
|
|
439
|
+
);
|
|
440
|
+
if (!response.ok) {
|
|
441
|
+
throw new Error(
|
|
442
|
+
`Failed to fetch assets manifest: ${response.status} ${response.statusText}`
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
const manifest = await response.json();
|
|
446
|
+
console.log("[Venus Mock] Loaded assets manifest:", {
|
|
447
|
+
version: manifest.version,
|
|
448
|
+
generatedAt: manifest.generatedAt,
|
|
449
|
+
categories: Object.keys(manifest.categories || {})
|
|
450
|
+
});
|
|
451
|
+
this.cachedAssets = manifest.categories || {};
|
|
452
|
+
this.cachedVersion = manifest.version;
|
|
453
|
+
return manifest;
|
|
454
|
+
} catch (error) {
|
|
455
|
+
console.error("[Venus Mock] Failed to load assets manifest:", error);
|
|
456
|
+
console.log(
|
|
457
|
+
"[Venus Mock] Using fallback minimal manifest for development"
|
|
458
|
+
);
|
|
459
|
+
const fallbackManifest = {
|
|
460
|
+
version: "dev-fallback",
|
|
461
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
462
|
+
categories: {
|
|
463
|
+
head: {
|
|
464
|
+
type: "mesh",
|
|
465
|
+
assets: [
|
|
466
|
+
{
|
|
467
|
+
id: "head_default",
|
|
468
|
+
filename: "head_default.glb",
|
|
469
|
+
displayName: "Default Head"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
id: "head_variant1",
|
|
473
|
+
filename: "head_variant1.glb",
|
|
474
|
+
displayName: "Head Variant 1"
|
|
475
|
+
}
|
|
476
|
+
]
|
|
477
|
+
},
|
|
478
|
+
outfit: {
|
|
479
|
+
type: "mesh",
|
|
480
|
+
assets: [
|
|
481
|
+
{
|
|
482
|
+
id: "outfit_default",
|
|
483
|
+
filename: "outfit_default.glb",
|
|
484
|
+
displayName: "Default Outfit"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
id: "outfit_casual",
|
|
488
|
+
filename: "outfit_casual.glb",
|
|
489
|
+
displayName: "Casual Outfit"
|
|
490
|
+
}
|
|
491
|
+
]
|
|
492
|
+
},
|
|
493
|
+
hat: {
|
|
494
|
+
type: "mesh",
|
|
495
|
+
assets: [
|
|
496
|
+
{
|
|
497
|
+
id: "hat_none",
|
|
498
|
+
filename: "hat_none.glb",
|
|
499
|
+
displayName: "No Hat"
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
id: "hat_cap",
|
|
503
|
+
filename: "hat_cap.glb",
|
|
504
|
+
displayName: "Baseball Cap"
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
},
|
|
508
|
+
hair: {
|
|
509
|
+
type: "mesh",
|
|
510
|
+
assets: [
|
|
511
|
+
{
|
|
512
|
+
id: "hair_default",
|
|
513
|
+
filename: "hair_default.glb",
|
|
514
|
+
displayName: "Default Hair"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
id: "hair_long",
|
|
518
|
+
filename: "hair_long.glb",
|
|
519
|
+
displayName: "Long Hair"
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
},
|
|
523
|
+
"face-accessory": {
|
|
524
|
+
type: "mesh",
|
|
525
|
+
assets: [
|
|
526
|
+
{
|
|
527
|
+
id: "glasses_none",
|
|
528
|
+
filename: "glasses_none.glb",
|
|
529
|
+
displayName: "No Glasses"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: "glasses_regular",
|
|
533
|
+
filename: "glasses_regular.glb",
|
|
534
|
+
displayName: "Regular Glasses"
|
|
535
|
+
}
|
|
536
|
+
]
|
|
537
|
+
},
|
|
538
|
+
animation: {
|
|
539
|
+
type: "mesh",
|
|
540
|
+
assets: [
|
|
541
|
+
{
|
|
542
|
+
id: "idle_default",
|
|
543
|
+
filename: "idle_default.glb",
|
|
544
|
+
displayName: "Default Idle"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
id: "wave",
|
|
548
|
+
filename: "wave.glb",
|
|
549
|
+
displayName: "Wave Animation"
|
|
550
|
+
}
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
this.cachedAssets = fallbackManifest.categories;
|
|
556
|
+
this.cachedVersion = fallbackManifest.version;
|
|
557
|
+
return fallbackManifest;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async selectAvatarConfig(avatarId = null, useDefaults = false) {
|
|
561
|
+
const categories = await this.getAssets();
|
|
562
|
+
this.log(`Manifest ${JSON.stringify(categories, null, 2)}`);
|
|
563
|
+
const rng = avatarId ? this.seededRandom(avatarId) : () => Math.random();
|
|
564
|
+
const headAsset = this.selectAsset(
|
|
565
|
+
categories,
|
|
566
|
+
"head",
|
|
567
|
+
rng,
|
|
568
|
+
avatarId,
|
|
569
|
+
useDefaults
|
|
570
|
+
);
|
|
571
|
+
const outfitAsset = this.selectAsset(
|
|
572
|
+
categories,
|
|
573
|
+
"outfit",
|
|
574
|
+
rng,
|
|
575
|
+
avatarId,
|
|
576
|
+
useDefaults
|
|
577
|
+
);
|
|
578
|
+
const hatAsset = this.selectAsset(
|
|
579
|
+
categories,
|
|
580
|
+
"hat",
|
|
581
|
+
rng,
|
|
582
|
+
avatarId,
|
|
583
|
+
useDefaults
|
|
584
|
+
);
|
|
585
|
+
const hairAsset = this.selectAsset(
|
|
586
|
+
categories,
|
|
587
|
+
"hair",
|
|
588
|
+
rng,
|
|
589
|
+
avatarId,
|
|
590
|
+
useDefaults
|
|
591
|
+
);
|
|
592
|
+
const faceAccessoryAsset = this.selectAsset(
|
|
593
|
+
categories,
|
|
594
|
+
"face-accessory",
|
|
595
|
+
rng,
|
|
596
|
+
avatarId,
|
|
597
|
+
useDefaults
|
|
598
|
+
);
|
|
599
|
+
const animationAsset = this.selectAsset(
|
|
600
|
+
categories,
|
|
601
|
+
"animation",
|
|
602
|
+
rng,
|
|
603
|
+
avatarId,
|
|
604
|
+
useDefaults
|
|
605
|
+
);
|
|
606
|
+
const config = {
|
|
607
|
+
headAsset: headAsset.filename,
|
|
608
|
+
outfitAsset: outfitAsset.filename,
|
|
609
|
+
animationAsset: animationAsset.filename,
|
|
610
|
+
faceAccessoryAsset: faceAccessoryAsset.filename,
|
|
611
|
+
hairAsset: hairAsset.filename,
|
|
612
|
+
hatAsset: hatAsset.filename,
|
|
613
|
+
skinColor: null
|
|
614
|
+
// NOTE(Zee): This was not selected anywhere?
|
|
615
|
+
};
|
|
616
|
+
console.log(
|
|
617
|
+
`[Venus Mock] Selected avatar config for ${avatarId || "default"}:`,
|
|
618
|
+
config
|
|
619
|
+
);
|
|
620
|
+
return config;
|
|
621
|
+
}
|
|
622
|
+
selectAsset(manifest, categoryId, rng, avatarId, useDefaults = false) {
|
|
623
|
+
const categoryAssets = manifest[categoryId].assets;
|
|
624
|
+
if (useDefaults) {
|
|
625
|
+
const selectedAsset2 = categoryAssets[0];
|
|
626
|
+
console.log(
|
|
627
|
+
`[Venus Mock] Using default asset for ${categoryId}:`,
|
|
628
|
+
selectedAsset2.id
|
|
629
|
+
);
|
|
630
|
+
return selectedAsset2;
|
|
631
|
+
}
|
|
632
|
+
if (avatarId) {
|
|
633
|
+
const index = Math.floor(rng() * categoryAssets.length);
|
|
634
|
+
const selectedAsset2 = categoryAssets[index];
|
|
635
|
+
console.log(
|
|
636
|
+
`[Venus Mock] Seeded selection for ${avatarId} ${categoryId}:`,
|
|
637
|
+
selectedAsset2.id,
|
|
638
|
+
`(index ${index}/${categoryAssets.length})`
|
|
639
|
+
);
|
|
640
|
+
return selectedAsset2;
|
|
641
|
+
}
|
|
642
|
+
const selectedAsset = categoryAssets[0];
|
|
643
|
+
this.log(`Fallback to first asset for ${categoryId}:`, selectedAsset.id);
|
|
644
|
+
return selectedAsset;
|
|
645
|
+
}
|
|
646
|
+
seededRandom(seed) {
|
|
647
|
+
const hash = this.simpleHash(seed);
|
|
648
|
+
let state = hash;
|
|
649
|
+
return function() {
|
|
650
|
+
state = (state * 1664525 + 1013904223) % 4294967296;
|
|
651
|
+
return state / 4294967296;
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
simpleHash(str) {
|
|
655
|
+
let hash = 0;
|
|
656
|
+
for (let i = 0; i < str.length; i++) {
|
|
657
|
+
const char = str.charCodeAt(i);
|
|
658
|
+
hash = (hash << 5) - hash + char;
|
|
659
|
+
hash = hash & hash;
|
|
660
|
+
}
|
|
661
|
+
return Math.abs(hash);
|
|
662
|
+
}
|
|
663
|
+
async getAllAssetPaths() {
|
|
664
|
+
const venusApi = this._venusApi;
|
|
665
|
+
const assets = await this.getAssets();
|
|
666
|
+
const allPaths = {};
|
|
667
|
+
for (const [category, categoryData] of Object.entries(assets)) {
|
|
668
|
+
allPaths[category] = (categoryData?.assets || []).map(
|
|
669
|
+
(asset) => venusApi.resolveAvatarAssetUrl(`${category}/${asset.filename}`)
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
this.log("All available asset paths:", allPaths);
|
|
673
|
+
return allPaths;
|
|
674
|
+
}
|
|
675
|
+
log(message, ...args) {
|
|
676
|
+
console.log(`"[Venus Mock] ${message}`, args);
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/avatar3d/RpcAvatarApi.ts
|
|
681
|
+
var RpcAvatarApi = class {
|
|
682
|
+
constructor(rpcClient, venusApi) {
|
|
683
|
+
__publicField(this, "venusApi");
|
|
684
|
+
__publicField(this, "rpcClient");
|
|
685
|
+
this.rpcClient = rpcClient;
|
|
686
|
+
this.venusApi = venusApi;
|
|
687
|
+
}
|
|
688
|
+
async downloadAssetPaths() {
|
|
689
|
+
const venusApi = this.venusApi;
|
|
690
|
+
console.log("[Venus] Downloading avatar3d asset paths...");
|
|
691
|
+
const manifestUrl = venusApi.resolveAvatarAssetUrl("assets.json");
|
|
692
|
+
console.log("[Venus] \u{1F50D} Manifest URL resolved to:", manifestUrl);
|
|
693
|
+
const manifest = await this.fetchFromCdn(manifestUrl);
|
|
694
|
+
console.log("[Venus] \u{1F4E6} Manifest loaded successfully:", {
|
|
695
|
+
version: manifest.version,
|
|
696
|
+
categories: Object.keys(manifest.categories || {}),
|
|
697
|
+
totalAssets: Object.values(manifest.categories || {}).reduce(function(sum, cat) {
|
|
698
|
+
return sum + (cat.assets?.length || 0);
|
|
699
|
+
}, 0)
|
|
700
|
+
});
|
|
701
|
+
const categories = manifest.categories || {};
|
|
702
|
+
const assetPaths = {};
|
|
703
|
+
for (const categoryKey in categories) {
|
|
704
|
+
const categoryData = categories[categoryKey];
|
|
705
|
+
const categoryPath = categoryKey;
|
|
706
|
+
const assetUrls = (categoryData?.assets || []).map((asset) => {
|
|
707
|
+
const url = venusApi.resolveAvatarAssetUrl(
|
|
708
|
+
categoryPath + "/" + asset.filename
|
|
709
|
+
);
|
|
710
|
+
console.log("[Venus] \u{1F3A8} Asset URL:", asset.filename, "->", url);
|
|
711
|
+
return url;
|
|
712
|
+
});
|
|
713
|
+
assetPaths[categoryKey] = assetUrls;
|
|
714
|
+
console.log(
|
|
715
|
+
"[Venus] \u{1F4C1} Category",
|
|
716
|
+
categoryKey,
|
|
717
|
+
"has",
|
|
718
|
+
assetUrls.length,
|
|
719
|
+
"assets"
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
console.log("[Venus] Avatar3d asset paths downloaded successfully");
|
|
723
|
+
return assetPaths;
|
|
724
|
+
}
|
|
725
|
+
async downloadManifest() {
|
|
726
|
+
console.log("[Venus] Downloading avatar3d manifest...");
|
|
727
|
+
const venusApi = this.venusApi;
|
|
728
|
+
const manifestUrl = venusApi.resolveAvatarAssetUrl("assets.json");
|
|
729
|
+
const manifest = await this.fetchFromCdn(manifestUrl);
|
|
730
|
+
console.log("[Venus] Avatar3d manifest downloaded successfully");
|
|
731
|
+
return manifest;
|
|
732
|
+
}
|
|
733
|
+
async loadAvatar(avatarId) {
|
|
734
|
+
const result = await this.rpcClient.call("H5_AVATAR3D_LOAD" /* AVATAR3D_LOAD */, {
|
|
735
|
+
avatar3dId: avatarId
|
|
736
|
+
});
|
|
737
|
+
this.log(
|
|
738
|
+
`Avatar loaded with the following result:
|
|
739
|
+
${JSON.stringify(result, null, 2)}`
|
|
740
|
+
);
|
|
741
|
+
return result;
|
|
742
|
+
}
|
|
743
|
+
saveAvatar(config) {
|
|
744
|
+
return this.rpcClient.call("H5_AVATAR3D_SAVE" /* AVATAR3D_SAVE */, {
|
|
745
|
+
config
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
deleteAvatar() {
|
|
749
|
+
return this.rpcClient.call("H5_AVATAR3D_DELETE" /* AVATAR3D_DELETE */);
|
|
750
|
+
}
|
|
751
|
+
async showEditor(options) {
|
|
752
|
+
const rpcClient = this.rpcClient;
|
|
753
|
+
console.log(
|
|
754
|
+
"[Venus] \u{1F3A8} showAvatar3dEditorAsync called with options:",
|
|
755
|
+
options
|
|
756
|
+
);
|
|
757
|
+
console.log(
|
|
758
|
+
"[Venus] \u{1F4E4} Sending H5_STACK_PUSH_REQUEST for avatar3d using _sendRequest..."
|
|
759
|
+
);
|
|
760
|
+
const rawResult = await rpcClient.call(
|
|
761
|
+
"H5_STACK_PUSH_REQUEST" /* H5_STACK_PUSH_REQUEST */,
|
|
762
|
+
{
|
|
763
|
+
targetAppId: "AVATAR3D",
|
|
764
|
+
contextData: options?.contextData || {},
|
|
765
|
+
appParams: {
|
|
766
|
+
currentAvatar: options?.currentAvatar,
|
|
767
|
+
onSave: options?.onSave,
|
|
768
|
+
onCancel: options?.onCancel
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
);
|
|
772
|
+
console.log(
|
|
773
|
+
"[Venus] \u2705 Avatar editor completed with raw result:",
|
|
774
|
+
rawResult
|
|
775
|
+
);
|
|
776
|
+
return {
|
|
777
|
+
wasChanged: rawResult.wasChanged || false,
|
|
778
|
+
config: rawResult.config || null,
|
|
779
|
+
savedAvatarId: rawResult.savedAvatarId || null
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
async fetchFromCdn(url) {
|
|
783
|
+
const response = await fetch(url, {
|
|
784
|
+
method: "GET",
|
|
785
|
+
headers: {
|
|
786
|
+
Accept: "application/json, text/plain, */*",
|
|
787
|
+
"Content-Type": "application/json"
|
|
788
|
+
},
|
|
789
|
+
mode: "cors",
|
|
790
|
+
cache: "no-cache"
|
|
791
|
+
});
|
|
792
|
+
if (!response.ok) {
|
|
793
|
+
throw new Error(
|
|
794
|
+
`CDN fetch failed: ${response.status} ${response.statusText}`
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
return await response.json();
|
|
798
|
+
}
|
|
799
|
+
log(message, ...options) {
|
|
800
|
+
console.log(`[Venus] ${message}`, options);
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
// src/avatar3d/index.ts
|
|
805
|
+
function initializeAvatar3d(venusApi, host) {
|
|
806
|
+
venusApi.loadAvatar3dAsync = host.avatar3d.loadAvatar.bind(host.avatar3d);
|
|
807
|
+
venusApi.saveAvatar3dAsync = host.avatar3d.saveAvatar.bind(host.avatar3d);
|
|
808
|
+
venusApi.deleteAvatar3dAsync = host.avatar3d.deleteAvatar.bind(host.avatar3d);
|
|
809
|
+
venusApi.downloadAvatar3dManifestAsync = host.avatar3d.downloadManifest.bind(
|
|
810
|
+
host.avatar3d
|
|
811
|
+
);
|
|
812
|
+
venusApi.showAvatar3dEditorAsync = host.avatar3d.showEditor.bind(
|
|
813
|
+
host.avatar3d
|
|
814
|
+
);
|
|
815
|
+
venusApi.downloadAvatar3dAssetPathsAsync = host.avatar3d.downloadAssetPaths.bind(host.avatar3d);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// src/cdn/HostCdnApi.ts
|
|
819
|
+
var HostCdnApi = class {
|
|
820
|
+
constructor(baseUrl) {
|
|
821
|
+
__publicField(this, "baseUrl");
|
|
822
|
+
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
823
|
+
}
|
|
824
|
+
async fetchBlob(path, options) {
|
|
825
|
+
const controller = new AbortController();
|
|
826
|
+
const timeoutId = setTimeout(
|
|
827
|
+
() => controller.abort(),
|
|
828
|
+
options?.timeout ?? 3e4
|
|
829
|
+
);
|
|
830
|
+
try {
|
|
831
|
+
const url = this.resolveAssetUrl(path);
|
|
832
|
+
const response = await fetch(url, {
|
|
833
|
+
mode: "cors",
|
|
834
|
+
credentials: "omit",
|
|
835
|
+
headers: { Accept: "/*" },
|
|
836
|
+
signal: controller.signal
|
|
837
|
+
});
|
|
838
|
+
clearTimeout(timeoutId);
|
|
839
|
+
if (!response.ok) {
|
|
840
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
841
|
+
}
|
|
842
|
+
return await response.blob();
|
|
843
|
+
} catch (error) {
|
|
844
|
+
clearTimeout(timeoutId);
|
|
845
|
+
throw error;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async fetchFromCdn(url, request) {
|
|
849
|
+
const response = await fetch(url, {
|
|
850
|
+
method: "GET",
|
|
851
|
+
headers: {
|
|
852
|
+
Accept: "application/json, text/plain, */*",
|
|
853
|
+
"Content-Type": "application/json"
|
|
854
|
+
},
|
|
855
|
+
mode: "cors",
|
|
856
|
+
cache: "no-cache"
|
|
857
|
+
});
|
|
858
|
+
if (!response.ok) {
|
|
859
|
+
throw new Error(
|
|
860
|
+
`CDN fetch failed: \${response.status} \${response.statusText}`
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
return response;
|
|
864
|
+
}
|
|
865
|
+
getAssetCdnBaseUrl() {
|
|
866
|
+
return this.baseUrl;
|
|
867
|
+
}
|
|
868
|
+
resolveAssetUrl(subPath) {
|
|
869
|
+
const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
|
|
870
|
+
const pathParts = cleanSubPath.split("/");
|
|
871
|
+
const encodedParts = pathParts.map((part, index) => {
|
|
872
|
+
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
873
|
+
});
|
|
874
|
+
const encodedSubPath = encodedParts.join("/");
|
|
875
|
+
const fullUrl = this.baseUrl + "/" + encodedSubPath;
|
|
876
|
+
return fullUrl;
|
|
877
|
+
}
|
|
878
|
+
resolveAvatarAssetUrl(subPath) {
|
|
879
|
+
const avatarSubPath = "avatar3d/" + subPath;
|
|
880
|
+
return this.resolveAssetUrl(avatarSubPath);
|
|
881
|
+
}
|
|
882
|
+
resolveSharedLibUrl(subPath) {
|
|
883
|
+
const libSubPath = "libs/" + subPath;
|
|
884
|
+
return this.resolveAssetUrl(libSubPath);
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
// src/cdn/MockCdnApi.ts
|
|
889
|
+
var MockCdnApi = class {
|
|
890
|
+
constructor() {
|
|
891
|
+
__publicField(this, "baseUrl");
|
|
892
|
+
this.baseUrl = "https://venus-static-01293ak.web.app/";
|
|
893
|
+
}
|
|
894
|
+
async fetchBlob(path, options) {
|
|
895
|
+
const controller = new AbortController();
|
|
896
|
+
const timeoutId = setTimeout(
|
|
897
|
+
() => controller.abort(),
|
|
898
|
+
options?.timeout ?? 3e4
|
|
899
|
+
);
|
|
900
|
+
try {
|
|
901
|
+
const url = this.resolveAssetUrl(path);
|
|
902
|
+
const response = await fetch(url, {
|
|
903
|
+
mode: "cors",
|
|
904
|
+
credentials: "omit",
|
|
905
|
+
headers: { Accept: "/*" },
|
|
906
|
+
signal: controller.signal
|
|
907
|
+
});
|
|
908
|
+
clearTimeout(timeoutId);
|
|
909
|
+
if (!response.ok) {
|
|
910
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
911
|
+
}
|
|
912
|
+
return await response.blob();
|
|
913
|
+
} catch (error) {
|
|
914
|
+
clearTimeout(timeoutId);
|
|
915
|
+
throw error;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
getAssetCdnBaseUrl() {
|
|
919
|
+
return this.baseUrl;
|
|
920
|
+
}
|
|
921
|
+
resolveAssetUrl(subPath) {
|
|
922
|
+
if (subPath.startsWith("http://") || subPath.startsWith("https://")) {
|
|
923
|
+
return subPath;
|
|
924
|
+
}
|
|
925
|
+
if (subPath.startsWith("cdn/")) {
|
|
926
|
+
return subPath;
|
|
927
|
+
}
|
|
928
|
+
const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
|
|
929
|
+
const pathParts = cleanSubPath.split("/");
|
|
930
|
+
const encodedParts = pathParts.map((part, index) => {
|
|
931
|
+
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
932
|
+
});
|
|
933
|
+
const encodedSubPath = encodedParts.join("/");
|
|
934
|
+
const fullUrl = `${this.baseUrl}${encodedSubPath}`;
|
|
935
|
+
return fullUrl;
|
|
936
|
+
}
|
|
937
|
+
resolveAvatarAssetUrl(subPath) {
|
|
938
|
+
if (subPath.startsWith("http://") || subPath.startsWith("https://")) {
|
|
939
|
+
return subPath;
|
|
940
|
+
}
|
|
941
|
+
const avatarSubPath = `avatar3d/${subPath}`;
|
|
942
|
+
return this.resolveAssetUrl(avatarSubPath);
|
|
943
|
+
}
|
|
944
|
+
resolveSharedLibUrl(subPath) {
|
|
945
|
+
if (subPath.startsWith("http://") || subPath.startsWith("https://")) {
|
|
946
|
+
return subPath;
|
|
947
|
+
}
|
|
948
|
+
const libSubPath = `libs/${subPath}`;
|
|
949
|
+
return this.resolveAssetUrl(libSubPath);
|
|
950
|
+
}
|
|
951
|
+
async fetchFromCdn(url, options) {
|
|
952
|
+
const allowedDomains = [
|
|
953
|
+
"venus-static-01293ak.web.app",
|
|
954
|
+
"firebasestorage.googleapis.com",
|
|
955
|
+
"cdn.venusapp.com",
|
|
956
|
+
"storage.googleapis.com"
|
|
957
|
+
];
|
|
958
|
+
let urlObj = null;
|
|
959
|
+
try {
|
|
960
|
+
let isAllowed = true;
|
|
961
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
962
|
+
urlObj = new URL(url);
|
|
963
|
+
isAllowed = allowedDomains.some(
|
|
964
|
+
(domain) => urlObj.hostname === domain || urlObj.hostname.endsWith("." + domain)
|
|
965
|
+
);
|
|
966
|
+
if (!isAllowed) {
|
|
967
|
+
const error = `Domain not allowed: ${urlObj.hostname}. Allowed domains: ${allowedDomains.join(", ")}`;
|
|
968
|
+
console.error("[Venus Network Mock] Security error:", error);
|
|
969
|
+
throw new Error(error);
|
|
970
|
+
}
|
|
971
|
+
} else {
|
|
972
|
+
urlObj = null;
|
|
973
|
+
}
|
|
974
|
+
const fetchUrl = urlObj ? urlObj.href : url;
|
|
975
|
+
const response = await fetch(fetchUrl, {
|
|
976
|
+
method: options?.method || "GET",
|
|
977
|
+
headers: {
|
|
978
|
+
Accept: "text/plain, application/octet-stream, application/json, */*",
|
|
979
|
+
...options?.headers
|
|
980
|
+
},
|
|
981
|
+
cache: options?.cache || "default",
|
|
982
|
+
mode: "cors"
|
|
983
|
+
});
|
|
984
|
+
if (!response.ok) {
|
|
985
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
986
|
+
}
|
|
987
|
+
return response;
|
|
988
|
+
} catch (error) {
|
|
989
|
+
if (error instanceof Error && error.message && (error.message.includes("CORS") || error.message.includes("preflight") || error.message.includes("Access-Control") || error.message.includes("cache-control"))) {
|
|
990
|
+
try {
|
|
991
|
+
const fallbackUrl = urlObj ? urlObj.href : url;
|
|
992
|
+
const fallbackResponse = await fetch(fallbackUrl, {
|
|
993
|
+
method: "GET",
|
|
994
|
+
mode: "cors",
|
|
995
|
+
cache: "default"
|
|
996
|
+
});
|
|
997
|
+
if (!fallbackResponse.ok) {
|
|
998
|
+
throw new Error(
|
|
999
|
+
`HTTP ${fallbackResponse.status}: ${fallbackResponse.statusText}`
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
const fallbackText = await fallbackResponse.text();
|
|
1003
|
+
return fallbackResponse;
|
|
1004
|
+
} catch (fallbackError) {
|
|
1005
|
+
console.error(
|
|
1006
|
+
"[Venus Network Mock] CORS fallback also failed (from network.js):",
|
|
1007
|
+
{
|
|
1008
|
+
url,
|
|
1009
|
+
originalError: error.message,
|
|
1010
|
+
fallbackError,
|
|
1011
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1012
|
+
}
|
|
1013
|
+
);
|
|
1014
|
+
throw new Error(
|
|
1015
|
+
`CORS error: ${error.message}. Fallback also failed: ${fallbackError}`
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
console.error("[Venus Network Mock] Fetch failed (from network.js):", {
|
|
1020
|
+
url,
|
|
1021
|
+
error,
|
|
1022
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1023
|
+
});
|
|
1024
|
+
throw error;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1029
|
+
// src/cdn/index.ts
|
|
1030
|
+
function initializeCdn(venusApi, host) {
|
|
1031
|
+
venusApi.resolveAssetUrl = function(subPath) {
|
|
1032
|
+
return host.cdn.resolveAssetUrl(subPath);
|
|
1033
|
+
};
|
|
1034
|
+
venusApi.resolveAvatarAssetUrl = function(subPath) {
|
|
1035
|
+
return host.cdn.resolveAvatarAssetUrl(subPath);
|
|
1036
|
+
};
|
|
1037
|
+
venusApi.resolveSharedLibUrl = function(subPath) {
|
|
1038
|
+
return host.cdn.resolveSharedLibUrl(subPath);
|
|
1039
|
+
};
|
|
1040
|
+
venusApi.getAssetCdnBaseUrl = function() {
|
|
1041
|
+
return host.cdn.getAssetCdnBaseUrl();
|
|
1042
|
+
};
|
|
1043
|
+
venusApi.fetchFromCdn = (url, options) => {
|
|
1044
|
+
return host.cdn.fetchFromCdn(url, options);
|
|
1045
|
+
};
|
|
1046
|
+
venusApi.cdn = host.cdn;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// src/features/RpcFeaturesApi.ts
|
|
1050
|
+
var RpcFeaturesApi = class {
|
|
1051
|
+
constructor(rcpClient) {
|
|
1052
|
+
__publicField(this, "rpcClient");
|
|
1053
|
+
this.rpcClient = rcpClient;
|
|
1054
|
+
}
|
|
1055
|
+
async getExperiment(experimentName) {
|
|
1056
|
+
console.log("[Venus] Getting Experiment", experimentName);
|
|
1057
|
+
return await this.rpcClient.call("H5_GET_EXPERIMENT" /* GET_EXPERIMENT */, {
|
|
1058
|
+
experimentName
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
async getFeatureFlag(flagName) {
|
|
1062
|
+
console.log("[Venus] Getting Feature Flag", flagName);
|
|
1063
|
+
return await this.rpcClient.call("H5_GET_FEATURE_FLAG" /* GET_FEATURE_FLAG */, {
|
|
1064
|
+
flagName
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
async getFeatureGate(gateName) {
|
|
1068
|
+
console.log("[Venus] Getting Feature Gate", gateName);
|
|
1069
|
+
return await this.rpcClient.call("H5_GET_FEATURE_GATE" /* GET_FEATURE_GATE */, {
|
|
1070
|
+
gateName
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
|
|
1075
|
+
// src/features/MockFeaturesApi.ts
|
|
1076
|
+
var MockFeaturesApi = class {
|
|
1077
|
+
async getExperiment(experimentName) {
|
|
1078
|
+
return null;
|
|
1079
|
+
}
|
|
1080
|
+
async getFeatureFlag(flagName) {
|
|
1081
|
+
return Promise.resolve(false);
|
|
1082
|
+
}
|
|
1083
|
+
getFeatureGate(gateName) {
|
|
1084
|
+
return Promise.resolve(false);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
// src/features/index.ts
|
|
1089
|
+
function initializeFeaturesApi(venusApi, host) {
|
|
1090
|
+
venusApi.getExperiment = (options) => {
|
|
1091
|
+
return host.features.getExperiment(options.experimentName);
|
|
1092
|
+
};
|
|
1093
|
+
venusApi.getFeatureGate = (options) => {
|
|
1094
|
+
return host.features.getFeatureGate(options.gateName);
|
|
1095
|
+
};
|
|
1096
|
+
venusApi.getFeatureFlag = (options) => {
|
|
1097
|
+
return host.features.getFeatureFlag(options.flagName);
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// src/haptics/HapticsApi.ts
|
|
1102
|
+
var HapticFeedbackStyle = /* @__PURE__ */ ((HapticFeedbackStyle2) => {
|
|
1103
|
+
HapticFeedbackStyle2["Light"] = "light";
|
|
1104
|
+
HapticFeedbackStyle2["Medium"] = "medium";
|
|
1105
|
+
HapticFeedbackStyle2["Heavy"] = "heavy";
|
|
1106
|
+
HapticFeedbackStyle2["Success"] = "success";
|
|
1107
|
+
HapticFeedbackStyle2["Warning"] = "warning";
|
|
1108
|
+
HapticFeedbackStyle2["Error"] = "error";
|
|
1109
|
+
return HapticFeedbackStyle2;
|
|
1110
|
+
})(HapticFeedbackStyle || {});
|
|
1111
|
+
|
|
1112
|
+
// src/haptics/RpcHapticsApi.ts
|
|
1113
|
+
var RpcHapticsApi = class {
|
|
1114
|
+
constructor(rpcClient) {
|
|
1115
|
+
__publicField(this, "rpcClient");
|
|
1116
|
+
this.rpcClient = rpcClient;
|
|
1117
|
+
}
|
|
1118
|
+
async triggerHapticAsync(style) {
|
|
1119
|
+
await this.rpcClient.call("H5_TRIGGER_HAPTIC" /* TRIGGER_HAPTIC */, {
|
|
1120
|
+
style
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
// src/haptics/MockHapticsApi.ts
|
|
1126
|
+
var MockHapticsApi = class {
|
|
1127
|
+
constructor(venusApi) {
|
|
1128
|
+
__publicField(this, "venusApi");
|
|
1129
|
+
this.venusApi = venusApi;
|
|
1130
|
+
}
|
|
1131
|
+
async triggerHapticAsync(style) {
|
|
1132
|
+
const venusApi = this.venusApi;
|
|
1133
|
+
if (!venusApi._mock.device.supportsHaptics) {
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
// src/haptics/index.ts
|
|
1140
|
+
function initializeHaptics(venusApi, host) {
|
|
1141
|
+
venusApi.triggerHapticAsync = (style) => {
|
|
1142
|
+
return host.haptics.triggerHapticAsync(style);
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// src/iap/RpcIapApi.ts
|
|
1147
|
+
var RpcIapApi = class {
|
|
1148
|
+
constructor(rpcClient) {
|
|
1149
|
+
__publicField(this, "rpcClient");
|
|
1150
|
+
this.rpcClient = rpcClient;
|
|
1151
|
+
}
|
|
1152
|
+
async getHardCurrencyBalance() {
|
|
1153
|
+
const response = await this.rpcClient.call(
|
|
1154
|
+
"H5_IAP_GET_WALLET" /* H5_IAP_GET_WALLET */
|
|
1155
|
+
);
|
|
1156
|
+
return response;
|
|
1157
|
+
}
|
|
1158
|
+
async spendCurrency(productId, cost, options) {
|
|
1159
|
+
const result = await this.rpcClient.callT("H5_IAP_SPEND_CURRENCY" /* H5_IAP_SPEND_CURRENCY */, {
|
|
1160
|
+
amount: cost,
|
|
1161
|
+
productId,
|
|
1162
|
+
screenName: options?.screenName
|
|
1163
|
+
});
|
|
1164
|
+
if (!result.success) {
|
|
1165
|
+
throw new Error(result.error);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
async openStore() {
|
|
1169
|
+
await this.rpcClient.call("H5_IAP_OPEN_STORE" /* H5_IAP_OPEN_STORE */);
|
|
1170
|
+
}
|
|
1171
|
+
async getCurrencyIcon() {
|
|
1172
|
+
return await this.rpcClient.call("H5_IAP_GET_CURRENCY_ICON" /* H5_IAP_GET_CURRENCY_ICON */);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
// src/iap/MockCurrencyIcon.ts
|
|
1177
|
+
var mockCurrencyIconBase64 = "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";
|
|
1178
|
+
|
|
1179
|
+
// src/iap/MockIapApi.ts
|
|
1180
|
+
var MockIapApi = class {
|
|
1181
|
+
constructor() {
|
|
1182
|
+
__publicField(this, "_hardCurrency", 100);
|
|
1183
|
+
}
|
|
1184
|
+
get hardCurrency() {
|
|
1185
|
+
return this._hardCurrency;
|
|
1186
|
+
}
|
|
1187
|
+
set hardCurrency(value) {
|
|
1188
|
+
this._hardCurrency = value;
|
|
1189
|
+
}
|
|
1190
|
+
async spendCurrency(productId, cost, options) {
|
|
1191
|
+
console.log(`[Mock IAP] Spending ${cost} on ${productId})`);
|
|
1192
|
+
const remainingHardCurrency = this._hardCurrency - cost;
|
|
1193
|
+
if (remainingHardCurrency < 0) {
|
|
1194
|
+
throw new Error(
|
|
1195
|
+
`Not enough hard currency. Expected ${cost}, found ${this._hardCurrency}`
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
this._hardCurrency = remainingHardCurrency;
|
|
1199
|
+
}
|
|
1200
|
+
async getHardCurrencyBalance() {
|
|
1201
|
+
console.log("[Mock IAP] get hard currency called");
|
|
1202
|
+
return this._hardCurrency;
|
|
1203
|
+
}
|
|
1204
|
+
async openStore() {
|
|
1205
|
+
console.log("[Mock IAP] open store called");
|
|
1206
|
+
}
|
|
1207
|
+
async getCurrencyIcon() {
|
|
1208
|
+
console.log("[Mock IAP] get currency icon called");
|
|
1209
|
+
return {
|
|
1210
|
+
base64Data: mockCurrencyIconBase64
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
// src/iap/index.ts
|
|
1216
|
+
function initializeIap(venusApiInstance, host) {
|
|
1217
|
+
venusApiInstance.iap = host.iap;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
// src/lifecycles/MockLifecycleApi.ts
|
|
1221
|
+
var MockLifecycleApi = class {
|
|
1222
|
+
constructor() {
|
|
1223
|
+
__publicField(this, "playCallbacks", []);
|
|
1224
|
+
__publicField(this, "pauseCallbacks", []);
|
|
1225
|
+
__publicField(this, "resumeCallbacks", []);
|
|
1226
|
+
__publicField(this, "quitCallbacks", []);
|
|
1227
|
+
__publicField(this, "showCallbacks", []);
|
|
1228
|
+
__publicField(this, "hideCallbacks", []);
|
|
1229
|
+
}
|
|
1230
|
+
onCleanup(callback) {
|
|
1231
|
+
}
|
|
1232
|
+
onShow(callback) {
|
|
1233
|
+
this.showCallbacks.push(callback);
|
|
1234
|
+
}
|
|
1235
|
+
onHide(callback) {
|
|
1236
|
+
this.hideCallbacks.push(callback);
|
|
1237
|
+
}
|
|
1238
|
+
onPause(callback) {
|
|
1239
|
+
this.pauseCallbacks.push(callback);
|
|
1240
|
+
}
|
|
1241
|
+
onPlay(callback) {
|
|
1242
|
+
this.playCallbacks.push(callback);
|
|
1243
|
+
}
|
|
1244
|
+
onQuit(callback) {
|
|
1245
|
+
this.quitCallbacks.push(callback);
|
|
1246
|
+
}
|
|
1247
|
+
onResume(callback) {
|
|
1248
|
+
this.resumeCallbacks.push(callback);
|
|
1249
|
+
}
|
|
1250
|
+
triggerOnPlayCallbacks(context) {
|
|
1251
|
+
for (const callback of this.playCallbacks) {
|
|
1252
|
+
callback(context);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
triggerOnPauseCallbacks() {
|
|
1256
|
+
for (const callback of this.pauseCallbacks) {
|
|
1257
|
+
callback();
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
triggerOnResumeCallbacks() {
|
|
1261
|
+
for (const callback of this.resumeCallbacks) {
|
|
1262
|
+
callback();
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
triggerOnShowCallbacks(context) {
|
|
1266
|
+
for (const callback of this.showCallbacks) {
|
|
1267
|
+
callback(context);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
triggerOnHideCallbacks() {
|
|
1271
|
+
for (const callback of this.hideCallbacks) {
|
|
1272
|
+
callback();
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
triggerOnQuitCallbacks() {
|
|
1276
|
+
for (const callback of this.quitCallbacks) {
|
|
1277
|
+
callback();
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
|
|
1282
|
+
// src/lifecycles/RpcLifecycleApi.ts
|
|
1283
|
+
var RpcLifecycleApi = class {
|
|
1284
|
+
constructor(rpcClient) {
|
|
1285
|
+
__publicField(this, "rpcClient");
|
|
1286
|
+
this.rpcClient = rpcClient;
|
|
1287
|
+
}
|
|
1288
|
+
onCleanup(callback) {
|
|
1289
|
+
this.rpcClient.onNotification("CLEANUP" /* CLEANUP */, callback);
|
|
1290
|
+
}
|
|
1291
|
+
onHide(callback) {
|
|
1292
|
+
this.rpcClient.onNotification("HIDDEN" /* HIDDEN */, callback);
|
|
1293
|
+
}
|
|
1294
|
+
onPause(callback) {
|
|
1295
|
+
this.rpcClient.onNotification("PAUSE" /* PAUSE */, callback);
|
|
1296
|
+
}
|
|
1297
|
+
onPlay(callback) {
|
|
1298
|
+
this.rpcClient.onNotification("PLAY" /* PLAY */, callback);
|
|
1299
|
+
}
|
|
1300
|
+
onQuit(callback) {
|
|
1301
|
+
this.rpcClient.onNotification("QUIT" /* QUIT */, callback);
|
|
1302
|
+
}
|
|
1303
|
+
onResume(callback) {
|
|
1304
|
+
this.rpcClient.onNotification("RESUME" /* RESUME */, callback);
|
|
1305
|
+
}
|
|
1306
|
+
onShow(callback) {
|
|
1307
|
+
this.rpcClient.onNotification("SHOWN" /* SHOWN */, callback);
|
|
1308
|
+
}
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1311
|
+
// src/lifecycles/index.ts
|
|
1312
|
+
function initializeLifecycleApi(venusApi, host) {
|
|
1313
|
+
venusApi.onPlay = (callback) => {
|
|
1314
|
+
host.lifecycle.onPlay(callback);
|
|
1315
|
+
};
|
|
1316
|
+
venusApi.onPause = (callback) => {
|
|
1317
|
+
host.lifecycle.onPause(callback);
|
|
1318
|
+
};
|
|
1319
|
+
venusApi.onResume = (callback) => {
|
|
1320
|
+
host.lifecycle.onResume(callback);
|
|
1321
|
+
};
|
|
1322
|
+
venusApi.onShow = (callback) => {
|
|
1323
|
+
host.lifecycle.onShow(callback);
|
|
1324
|
+
};
|
|
1325
|
+
venusApi.onHide = (callback) => {
|
|
1326
|
+
host.lifecycle.onHide(callback);
|
|
1327
|
+
};
|
|
1328
|
+
venusApi.onQuit = (callback) => {
|
|
1329
|
+
host.lifecycle.onQuit(callback);
|
|
1330
|
+
};
|
|
1331
|
+
venusApi.onCleanup = (callback) => {
|
|
1332
|
+
host.lifecycle.onCleanup(callback);
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
// src/logging/MockLoggingApi.ts
|
|
1337
|
+
var MockLoggingApi = class {
|
|
1338
|
+
logDebug(message, ...args) {
|
|
1339
|
+
console.log(`[Venus Mock] ${message}`, args);
|
|
1340
|
+
}
|
|
1341
|
+
logError(message, ...args) {
|
|
1342
|
+
console.error(`[Venus Mock] ${message}`, args);
|
|
1343
|
+
}
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
// src/logging/RpcLoggingApi.ts
|
|
1347
|
+
var RpcLoggingApi = class {
|
|
1348
|
+
constructor(host, rpcClient) {
|
|
1349
|
+
__publicField(this, "host");
|
|
1350
|
+
__publicField(this, "rpcClient");
|
|
1351
|
+
this.host = host;
|
|
1352
|
+
this.rpcClient = rpcClient;
|
|
1353
|
+
}
|
|
1354
|
+
logDebug(message, ...args) {
|
|
1355
|
+
if (!this.host.isInitialized) {
|
|
1356
|
+
console.log(message, args);
|
|
1357
|
+
} else {
|
|
1358
|
+
message = this.buildMessage(message, ...args);
|
|
1359
|
+
this.rpcClient.call("H5_DEBUG" /* DEBUG */, { level: "log", message });
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
logError(message, ...args) {
|
|
1363
|
+
if (!this.host.isInitialized) {
|
|
1364
|
+
console.log(message, ...args);
|
|
1365
|
+
} else {
|
|
1366
|
+
message = this.buildMessage(message, ...args);
|
|
1367
|
+
this.rpcClient.call("H5_DEBUG" /* DEBUG */, {
|
|
1368
|
+
level: "error",
|
|
1369
|
+
message
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
buildMessage(message, ...args) {
|
|
1374
|
+
if (args && args.length > 0) {
|
|
1375
|
+
const stringArgs = [];
|
|
1376
|
+
for (const arg of args) {
|
|
1377
|
+
const argAsString = this.toStringArg(arg);
|
|
1378
|
+
if (argAsString) {
|
|
1379
|
+
stringArgs.push(argAsString);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
message += stringArgs.join(" ");
|
|
1383
|
+
}
|
|
1384
|
+
return message;
|
|
1385
|
+
}
|
|
1386
|
+
toStringArg(arg) {
|
|
1387
|
+
if (arg) {
|
|
1388
|
+
if (typeof arg === "object") {
|
|
1389
|
+
try {
|
|
1390
|
+
return JSON.stringify(arg);
|
|
1391
|
+
} catch (e) {
|
|
1392
|
+
return String(arg);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
return String(arg);
|
|
1396
|
+
}
|
|
1397
|
+
return void 0;
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
// src/logging/index.ts
|
|
1402
|
+
function initializeLoggingApi(venusApi, host) {
|
|
1403
|
+
venusApi.log = (message, ...args) => {
|
|
1404
|
+
return host.logging.logDebug(message, ...args);
|
|
1405
|
+
};
|
|
1406
|
+
venusApi.error = (message, ...args) => {
|
|
1407
|
+
return host.logging.logError(message, ...args);
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
// src/navigation/MockNavigationApi.ts
|
|
1412
|
+
var MockNavigationApi = class {
|
|
1413
|
+
constructor(venusApi) {
|
|
1414
|
+
__publicField(this, "venusApi");
|
|
1415
|
+
this.venusApi = venusApi;
|
|
1416
|
+
}
|
|
1417
|
+
async requestPopOrQuit(options) {
|
|
1418
|
+
return true;
|
|
1419
|
+
}
|
|
1420
|
+
getStackInfo() {
|
|
1421
|
+
const venusApi = this.venusApi;
|
|
1422
|
+
const info = {
|
|
1423
|
+
isInStack: venusApi._mock.stackState.isInStack,
|
|
1424
|
+
stackPosition: venusApi._mock.stackState.stackPosition,
|
|
1425
|
+
isTopOfStack: venusApi._mock.stackState.isTopOfStack,
|
|
1426
|
+
stackDepth: venusApi._mock.stackState.stackDepth,
|
|
1427
|
+
parentInstanceId: venusApi._mock.stackState.parentInstanceId
|
|
1428
|
+
};
|
|
1429
|
+
return info;
|
|
1430
|
+
}
|
|
1431
|
+
async popApp() {
|
|
1432
|
+
const venusApi = this.venusApi;
|
|
1433
|
+
if (venusApi._mock.stackState.stackDepth <= 1) {
|
|
1434
|
+
console.warn("[Venus Mock] Cannot pop - at base of stack or not in stack");
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
1438
|
+
const poppedApp = venusApi._mock.stackState.stackHistory.pop();
|
|
1439
|
+
venusApi._mock.stackState.stackDepth--;
|
|
1440
|
+
venusApi._mock.stackState.stackPosition = Math.max(
|
|
1441
|
+
0,
|
|
1442
|
+
venusApi._mock.stackState.stackDepth - 1
|
|
1443
|
+
);
|
|
1444
|
+
if (venusApi._mock.stackState.stackDepth === 0) {
|
|
1445
|
+
venusApi._mock.stackState.isInStack = false;
|
|
1446
|
+
venusApi._mock.stackState.isTopOfStack = false;
|
|
1447
|
+
venusApi._mock.stackState.parentInstanceId = null;
|
|
1448
|
+
}
|
|
1449
|
+
this.log("App popped: ", poppedApp);
|
|
1450
|
+
}
|
|
1451
|
+
async pushApp(appId, options) {
|
|
1452
|
+
const venusApi = this.venusApi;
|
|
1453
|
+
await createMockDelay(MOCK_DELAYS.medium);
|
|
1454
|
+
venusApi._mock.stackState.stackHistory.push({
|
|
1455
|
+
appId,
|
|
1456
|
+
pushedAt: Date.now(),
|
|
1457
|
+
contextData: options?.contextData,
|
|
1458
|
+
appParams: options?.appParams
|
|
1459
|
+
});
|
|
1460
|
+
venusApi._mock.stackState.isInStack = true;
|
|
1461
|
+
venusApi._mock.stackState.stackDepth++;
|
|
1462
|
+
venusApi._mock.stackState.stackPosition = venusApi._mock.stackState.stackDepth - 1;
|
|
1463
|
+
venusApi._mock.stackState.isTopOfStack = true;
|
|
1464
|
+
const pushedInstanceId = `mock-stack-${appId}-${Date.now()}`;
|
|
1465
|
+
this.log("PushedInstanceId: ", pushedInstanceId);
|
|
1466
|
+
}
|
|
1467
|
+
log(message, ...args) {
|
|
1468
|
+
console.log(`[Venus Mock] ${message}`, ...args);
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
// src/navigation/RpcNavigationApi.ts
|
|
1473
|
+
var RpcNavigationApi = class {
|
|
1474
|
+
constructor(rpcClient, venusApi) {
|
|
1475
|
+
__publicField(this, "venusApi");
|
|
1476
|
+
__publicField(this, "rpcClient");
|
|
1477
|
+
this.rpcClient = rpcClient;
|
|
1478
|
+
this.venusApi = venusApi;
|
|
1479
|
+
}
|
|
1480
|
+
async requestPopOrQuit(options) {
|
|
1481
|
+
const result = await this.rpcClient.call(
|
|
1482
|
+
"QUIT" /* QUIT */,
|
|
1483
|
+
options
|
|
1484
|
+
);
|
|
1485
|
+
return result.success;
|
|
1486
|
+
}
|
|
1487
|
+
getStackInfo() {
|
|
1488
|
+
this.venusApi;
|
|
1489
|
+
console.log("[Venus] getStackInfo called");
|
|
1490
|
+
const config = window.venus._config;
|
|
1491
|
+
const stackInfo = config.context?.stack || {
|
|
1492
|
+
isInStack: false,
|
|
1493
|
+
stackPosition: 0,
|
|
1494
|
+
parentInstanceId: null,
|
|
1495
|
+
appType: "standalone"
|
|
1496
|
+
};
|
|
1497
|
+
return stackInfo;
|
|
1498
|
+
}
|
|
1499
|
+
popApp() {
|
|
1500
|
+
const rpcClient = this.rpcClient;
|
|
1501
|
+
console.log("[Venus] popAppAsync called");
|
|
1502
|
+
return rpcClient.call("H5_STACK_POP_REQUEST" /* H5_STACK_POP_REQUEST */);
|
|
1503
|
+
}
|
|
1504
|
+
pushApp(appId, options) {
|
|
1505
|
+
const rpcClient = this.rpcClient;
|
|
1506
|
+
console.log("[Venus] pushAppAsync called", { appId, options });
|
|
1507
|
+
return rpcClient.call("H5_STACK_PUSH_REQUEST" /* H5_STACK_PUSH_REQUEST */, {
|
|
1508
|
+
targetAppId: appId,
|
|
1509
|
+
contextData: options?.contextData,
|
|
1510
|
+
appParams: options?.appParams
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
// src/navigation/index.ts
|
|
1516
|
+
function initializeStackNavigation(venusApi, host) {
|
|
1517
|
+
venusApi._mock.stackState = {
|
|
1518
|
+
isInStack: false,
|
|
1519
|
+
stackPosition: 0,
|
|
1520
|
+
stackDepth: 0,
|
|
1521
|
+
isTopOfStack: false,
|
|
1522
|
+
parentInstanceId: null,
|
|
1523
|
+
stackHistory: []
|
|
1524
|
+
// Track navigation history for mock
|
|
1525
|
+
};
|
|
1526
|
+
venusApi.pushAppAsync = host.navigation.pushApp.bind(host.navigation);
|
|
1527
|
+
venusApi.popAppAsync = host.navigation.popApp.bind(host.navigation);
|
|
1528
|
+
venusApi.getStackInfo = host.navigation.getStackInfo.bind(host.navigation);
|
|
1529
|
+
venusApi.requestPopOrQuit = (options) => {
|
|
1530
|
+
return host.navigation.requestPopOrQuit(options);
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
// src/notifications/MockNotificationsApi.ts
|
|
1535
|
+
var MockNotificationsApi = class {
|
|
1536
|
+
constructor(venusApi) {
|
|
1537
|
+
__publicField(this, "venusApi");
|
|
1538
|
+
this.venusApi = venusApi;
|
|
1539
|
+
}
|
|
1540
|
+
async cancelLocalNotification(notificationId) {
|
|
1541
|
+
const venusApi = this.venusApi;
|
|
1542
|
+
if (isWebPlatform()) {
|
|
1543
|
+
console.log(
|
|
1544
|
+
"[Venus Mock] Cancel notification on web platform (simulated):",
|
|
1545
|
+
notificationId
|
|
1546
|
+
);
|
|
1547
|
+
return true;
|
|
1548
|
+
}
|
|
1549
|
+
console.log("[Venus Mock] Cancel local notification:", notificationId);
|
|
1550
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
1551
|
+
if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
|
|
1552
|
+
delete venusApi._mock.scheduledNotifications[notificationId];
|
|
1553
|
+
return true;
|
|
1554
|
+
}
|
|
1555
|
+
return false;
|
|
1556
|
+
}
|
|
1557
|
+
async getAllScheduledLocalNotifications() {
|
|
1558
|
+
if (isWebPlatform()) {
|
|
1559
|
+
console.log(
|
|
1560
|
+
"[Venus Mock] Get notifications on web platform (returning empty list)"
|
|
1561
|
+
);
|
|
1562
|
+
return [];
|
|
1563
|
+
}
|
|
1564
|
+
console.log("[Venus Mock] Get all scheduled local notifications");
|
|
1565
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
1566
|
+
const venusApi = this.venusApi;
|
|
1567
|
+
const notifications = venusApi._mock.scheduledNotifications || {};
|
|
1568
|
+
return Object.values(notifications);
|
|
1569
|
+
}
|
|
1570
|
+
async isLocalNotificationsEnabled() {
|
|
1571
|
+
if (isWebPlatform()) {
|
|
1572
|
+
console.log("[Venus Mock] Notifications not available on web platform");
|
|
1573
|
+
return false;
|
|
1574
|
+
}
|
|
1575
|
+
console.log("[Venus Mock] Check if local notifications are enabled");
|
|
1576
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
1577
|
+
const venusApi = this.venusApi;
|
|
1578
|
+
const isEnabled = venusApi._mock.notificationsEnabled !== false;
|
|
1579
|
+
return isEnabled;
|
|
1580
|
+
}
|
|
1581
|
+
async scheduleLocalNotification(title, body, options) {
|
|
1582
|
+
if (isWebPlatform()) {
|
|
1583
|
+
console.log(
|
|
1584
|
+
"[Venus Mock] Notifications not supported on web platform, simulating success"
|
|
1585
|
+
);
|
|
1586
|
+
console.info(
|
|
1587
|
+
"\u{1F514} [Venus Mock] Notification would be scheduled:",
|
|
1588
|
+
title || "Untitled",
|
|
1589
|
+
"\n Body:",
|
|
1590
|
+
body || "No body",
|
|
1591
|
+
"\n This is a simulation - real notifications require a native platform."
|
|
1592
|
+
);
|
|
1593
|
+
const mockId = `mock-web-notification-${Date.now()}`;
|
|
1594
|
+
return mockId;
|
|
1595
|
+
}
|
|
1596
|
+
console.log("[Venus Mock] Schedule local notification:", options);
|
|
1597
|
+
const venusApi = this.venusApi;
|
|
1598
|
+
if (!venusApi._mock.pendingRequests) {
|
|
1599
|
+
console.log("[Venus Mock] Initializing pendingRequests");
|
|
1600
|
+
venusApi._mock.pendingRequests = {};
|
|
1601
|
+
}
|
|
1602
|
+
const requestId = Date.now().toString();
|
|
1603
|
+
console.log("[Venus Mock] Creating request with ID:", requestId);
|
|
1604
|
+
return new Promise((resolve) => {
|
|
1605
|
+
venusApi._mock.pendingRequests[requestId] = { resolve };
|
|
1606
|
+
const notificationId = `mock-notification-${Date.now()}`;
|
|
1607
|
+
if (!venusApi._mock.scheduledNotifications) {
|
|
1608
|
+
venusApi._mock.scheduledNotifications = {};
|
|
1609
|
+
}
|
|
1610
|
+
venusApi._mock.scheduledNotifications[notificationId] = {
|
|
1611
|
+
...options,
|
|
1612
|
+
id: notificationId,
|
|
1613
|
+
createdAt: Date.now()
|
|
1614
|
+
};
|
|
1615
|
+
setTimeout(() => {
|
|
1616
|
+
resolve(notificationId);
|
|
1617
|
+
}, MOCK_DELAYS.short);
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
async setLocalNotificationsEnabled(enabled) {
|
|
1621
|
+
const venusApi = this.venusApi;
|
|
1622
|
+
if (isWebPlatform()) {
|
|
1623
|
+
console.log(
|
|
1624
|
+
"[Venus Mock] Set notifications enabled on web platform (simulated):",
|
|
1625
|
+
enabled
|
|
1626
|
+
);
|
|
1627
|
+
return true;
|
|
1628
|
+
}
|
|
1629
|
+
console.log("[Venus Mock] Set local notifications enabled:", enabled);
|
|
1630
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
1631
|
+
venusApi._mock.notificationsEnabled = enabled;
|
|
1632
|
+
return enabled;
|
|
1633
|
+
}
|
|
1634
|
+
};
|
|
1635
|
+
|
|
1636
|
+
// src/notifications/index.ts
|
|
1637
|
+
function initializeLocalNotifications(venusApi, host) {
|
|
1638
|
+
venusApi.setLocalNotifEnabledAsync = async (enable) => {
|
|
1639
|
+
await host.notifications.setLocalNotificationsEnabled(enable);
|
|
1640
|
+
};
|
|
1641
|
+
venusApi.isLocalNotifEnabledAsync = async () => {
|
|
1642
|
+
return host.notifications.isLocalNotificationsEnabled();
|
|
1643
|
+
};
|
|
1644
|
+
venusApi.getAllLocalNotifsAsync = async () => {
|
|
1645
|
+
return host.notifications.getAllScheduledLocalNotifications();
|
|
1646
|
+
};
|
|
1647
|
+
venusApi.cancelLocalNotifAsync = async (notificationId) => {
|
|
1648
|
+
await host.notifications.cancelLocalNotification(notificationId);
|
|
1649
|
+
};
|
|
1650
|
+
venusApi.scheduleLocalNotifAsync = async (options) => {
|
|
1651
|
+
const id = await host.notifications.scheduleLocalNotification(
|
|
1652
|
+
options.title,
|
|
1653
|
+
options.body,
|
|
1654
|
+
{
|
|
1655
|
+
trigger: options.trigger,
|
|
1656
|
+
priority: options.priority,
|
|
1657
|
+
groupId: options.groupId,
|
|
1658
|
+
payload: options.payload
|
|
1659
|
+
}
|
|
1660
|
+
);
|
|
1661
|
+
if (id) {
|
|
1662
|
+
return id;
|
|
1663
|
+
}
|
|
1664
|
+
return "";
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
// src/popups/RpcPopupsApi.ts
|
|
1669
|
+
var RpcPopupsApi = class {
|
|
1670
|
+
constructor(rpcClient) {
|
|
1671
|
+
__publicField(this, "rpcClient");
|
|
1672
|
+
this.rpcClient = rpcClient;
|
|
1673
|
+
}
|
|
1674
|
+
async showActionSheet(items, options) {
|
|
1675
|
+
const result = await this.rpcClient.call(
|
|
1676
|
+
"H5_ACTION_SHEET_SHOW" /* ACTION_SHEET_SHOW */,
|
|
1677
|
+
{
|
|
1678
|
+
title: options?.title || "",
|
|
1679
|
+
message: options?.message || "",
|
|
1680
|
+
options: items,
|
|
1681
|
+
cancelButtonText: options?.cancelButtonText || "Cancel"
|
|
1682
|
+
}
|
|
1683
|
+
);
|
|
1684
|
+
return result;
|
|
1685
|
+
}
|
|
1686
|
+
async showAlert(title, message, options) {
|
|
1687
|
+
const buttonText = options?.buttonText || "OK";
|
|
1688
|
+
await this.rpcClient.call("H5_ALERT_DIALOG" /* ALERT_DIALOG */, {
|
|
1689
|
+
title,
|
|
1690
|
+
message,
|
|
1691
|
+
buttonText
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
async showConfirm(title, message, options) {
|
|
1695
|
+
const confirmText = options?.confirmText || "OK";
|
|
1696
|
+
const cancelText = options?.cancelText || "Cancel";
|
|
1697
|
+
const result = await this.rpcClient.call(
|
|
1698
|
+
"H5_CONFIRM_DIALOG" /* CONFIRM_DIALOG */,
|
|
1699
|
+
{
|
|
1700
|
+
title,
|
|
1701
|
+
message,
|
|
1702
|
+
confirmText,
|
|
1703
|
+
cancelText
|
|
1704
|
+
}
|
|
1705
|
+
);
|
|
1706
|
+
return result;
|
|
1707
|
+
}
|
|
1708
|
+
async showToast(message, options) {
|
|
1709
|
+
const duration = options?.duration ?? 3e3;
|
|
1710
|
+
const variant = options?.variant ?? "info";
|
|
1711
|
+
const response = await this.rpcClient.call(
|
|
1712
|
+
"H5_TOAST" /* TOAST */,
|
|
1713
|
+
{
|
|
1714
|
+
message,
|
|
1715
|
+
duration,
|
|
1716
|
+
variant,
|
|
1717
|
+
action: options?.action
|
|
1718
|
+
},
|
|
1719
|
+
duration + 2e3
|
|
1720
|
+
);
|
|
1721
|
+
return response.actionTriggered;
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
// src/popups/MockPopupsApi.ts
|
|
1726
|
+
var MockPopupsApi = class {
|
|
1727
|
+
constructor(override) {
|
|
1728
|
+
__publicField(this, "overlay");
|
|
1729
|
+
this.overlay = override;
|
|
1730
|
+
}
|
|
1731
|
+
showActionSheet(items, options) {
|
|
1732
|
+
console.log(
|
|
1733
|
+
`[Venus Mock] Show Action sheet, items: ${JSON.stringify(items, null, 2)}, options: ${JSON.stringify(options, null, 2)}`
|
|
1734
|
+
);
|
|
1735
|
+
return this.overlay.showActionSheet(items, options);
|
|
1736
|
+
}
|
|
1737
|
+
async showAlert(title, message, options) {
|
|
1738
|
+
window.alert(`${title}
|
|
1739
|
+
${message}`);
|
|
1740
|
+
}
|
|
1741
|
+
async showConfirm(title, message, options) {
|
|
1742
|
+
const result = window.confirm(`${title || "Confirm"}
|
|
1743
|
+
${message}`);
|
|
1744
|
+
return result;
|
|
1745
|
+
}
|
|
1746
|
+
async showToast(message, options) {
|
|
1747
|
+
const variant = options?.variant ?? "info";
|
|
1748
|
+
const duration = options?.duration ?? 3e3;
|
|
1749
|
+
const action = options?.action;
|
|
1750
|
+
console.log("[Venus Mock] Toast:", message, {
|
|
1751
|
+
variant,
|
|
1752
|
+
duration,
|
|
1753
|
+
hasAction: !!action
|
|
1754
|
+
});
|
|
1755
|
+
if (action) {
|
|
1756
|
+
const actionResult = window.confirm(
|
|
1757
|
+
`${message}
|
|
1758
|
+
|
|
1759
|
+
[${action.label}] or [Cancel]`
|
|
1760
|
+
);
|
|
1761
|
+
if (actionResult) {
|
|
1762
|
+
console.log("[Venus Mock] Toast action triggered:", action.label);
|
|
1763
|
+
return true;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1769
|
+
|
|
1770
|
+
// src/popups/index.ts
|
|
1771
|
+
function initializePopups(venusApi, host) {
|
|
1772
|
+
venusApi.showToast = async (input) => {
|
|
1773
|
+
if (typeof input === "string") {
|
|
1774
|
+
return await host.popups.showToast(input);
|
|
1775
|
+
} else {
|
|
1776
|
+
return await host.popups.showToast(input.message, {
|
|
1777
|
+
duration: input.duration,
|
|
1778
|
+
action: input.action,
|
|
1779
|
+
variant: "success"
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
};
|
|
1783
|
+
venusApi.showAlert = async (input) => {
|
|
1784
|
+
await host.popups.showAlert(input.title, input.message, {
|
|
1785
|
+
buttonText: input.buttonText
|
|
1786
|
+
});
|
|
1787
|
+
};
|
|
1788
|
+
venusApi.showConfirm = async (input) => {
|
|
1789
|
+
const confirmed = await host.popups.showConfirm(
|
|
1790
|
+
input.title,
|
|
1791
|
+
input.message,
|
|
1792
|
+
{
|
|
1793
|
+
confirmText: input.confirmText,
|
|
1794
|
+
cancelText: input.cancelText
|
|
1795
|
+
}
|
|
1796
|
+
);
|
|
1797
|
+
return confirmed;
|
|
1798
|
+
};
|
|
1799
|
+
venusApi.showActionSheet = async (input) => {
|
|
1800
|
+
return await host.popups.showActionSheet(input.options, {
|
|
1801
|
+
title: input.title,
|
|
1802
|
+
message: input.message,
|
|
1803
|
+
cancelButtonText: input.cancelButtonText,
|
|
1804
|
+
disableCancel: input.disableCancel
|
|
1805
|
+
});
|
|
1806
|
+
};
|
|
1807
|
+
venusApi.popups = host.popups;
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
// src/profile/HostProfileApi.ts
|
|
1811
|
+
var HostProfileApi = class {
|
|
1812
|
+
getCurrentProfile() {
|
|
1813
|
+
if (window.venus._config && window.venus._config.profile) {
|
|
1814
|
+
return {
|
|
1815
|
+
id: window.venus._config.profile.id || "unknown",
|
|
1816
|
+
name: window.venus._config.profile.username || "Unknown User",
|
|
1817
|
+
username: window.venus._config.profile.username || "unknown"
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
return {
|
|
1821
|
+
id: "mock_profile_123",
|
|
1822
|
+
name: "Mock User",
|
|
1823
|
+
username: "mockuser"
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
|
|
1828
|
+
// src/profile/MockProfileApi.ts
|
|
1829
|
+
var MockProfileApi = class {
|
|
1830
|
+
getCurrentProfile() {
|
|
1831
|
+
return {
|
|
1832
|
+
id: "mock_profile_123",
|
|
1833
|
+
name: "Mock User",
|
|
1834
|
+
username: "mockuser"
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
|
|
1839
|
+
// src/profile/index.ts
|
|
1840
|
+
function initializeProfile(venusApi, host) {
|
|
1841
|
+
venusApi.getCurrentProfile = () => {
|
|
1842
|
+
return host.profile.getCurrentProfile();
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// src/rpc/RpcClient.ts
|
|
1847
|
+
var RpcClient = class {
|
|
1848
|
+
constructor() {
|
|
1849
|
+
__publicField(this, "pendingCalls", /* @__PURE__ */ new Map());
|
|
1850
|
+
__publicField(this, "notificationCallbacks", /* @__PURE__ */ new Map());
|
|
1851
|
+
__publicField(this, "onResponseSub", null);
|
|
1852
|
+
__publicField(this, "onNotificationSub", null);
|
|
1853
|
+
__publicField(this, "transport", null);
|
|
1854
|
+
}
|
|
1855
|
+
start(transport) {
|
|
1856
|
+
this.transport = transport;
|
|
1857
|
+
this.onResponseSub = transport.onResponse(async (response) => {
|
|
1858
|
+
return this.handleRpcResponse(response);
|
|
1859
|
+
});
|
|
1860
|
+
this.onNotificationSub = transport.onNotification(async (notification) => {
|
|
1861
|
+
return this.handleRpcNotification(notification);
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
stop() {
|
|
1865
|
+
if (this.onResponseSub) {
|
|
1866
|
+
this.onResponseSub.unsubscribe();
|
|
1867
|
+
this.onResponseSub = null;
|
|
1868
|
+
}
|
|
1869
|
+
if (this.onNotificationSub) {
|
|
1870
|
+
this.onNotificationSub.unsubscribe();
|
|
1871
|
+
this.onNotificationSub = null;
|
|
1872
|
+
}
|
|
1873
|
+
this.transport = null;
|
|
1874
|
+
}
|
|
1875
|
+
onNotification(id, callback) {
|
|
1876
|
+
this.notificationCallbacks.set(id, callback);
|
|
1877
|
+
return {
|
|
1878
|
+
unsubscribe: () => {
|
|
1879
|
+
this.notificationCallbacks.delete(id);
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
callT(method, args, timeout = 5e3) {
|
|
1884
|
+
return this.call(method, args, timeout);
|
|
1885
|
+
}
|
|
1886
|
+
async call(method, args, timeout = 5e3) {
|
|
1887
|
+
return new Promise((resolve, reject) => {
|
|
1888
|
+
const id = this.generateId();
|
|
1889
|
+
this.addPendingCall(id, resolve, reject);
|
|
1890
|
+
const request = {
|
|
1891
|
+
type: "rpc-request",
|
|
1892
|
+
id,
|
|
1893
|
+
method,
|
|
1894
|
+
args
|
|
1895
|
+
};
|
|
1896
|
+
if (this.transport) {
|
|
1897
|
+
this.transport.sendRequest(request);
|
|
1898
|
+
}
|
|
1899
|
+
if (timeout > 0) {
|
|
1900
|
+
setTimeout(() => {
|
|
1901
|
+
if (this.hasPendingCall(id)) {
|
|
1902
|
+
this.removePendingCall(id);
|
|
1903
|
+
reject(new Error(`RPC call ${method} timed out`));
|
|
1904
|
+
}
|
|
1905
|
+
}, timeout);
|
|
1906
|
+
}
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
hasPendingCall(id) {
|
|
1910
|
+
return this.pendingCalls.has(id);
|
|
1911
|
+
}
|
|
1912
|
+
addPendingCall(id, resolve, reject) {
|
|
1913
|
+
this.pendingCalls.set(id, {
|
|
1914
|
+
id,
|
|
1915
|
+
resolve,
|
|
1916
|
+
reject
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1919
|
+
removePendingCall(id) {
|
|
1920
|
+
this.pendingCalls.delete(id);
|
|
1921
|
+
}
|
|
1922
|
+
getPendingCall(id) {
|
|
1923
|
+
return this.pendingCalls.get(id);
|
|
1924
|
+
}
|
|
1925
|
+
generateId() {
|
|
1926
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1927
|
+
}
|
|
1928
|
+
handleRpcResponse(response) {
|
|
1929
|
+
const pending = this.getPendingCall(response.id);
|
|
1930
|
+
if (!pending) {
|
|
1931
|
+
return false;
|
|
1932
|
+
}
|
|
1933
|
+
this.removePendingCall(response.id);
|
|
1934
|
+
if (response.error) {
|
|
1935
|
+
pending.reject(new Error(response.error.message));
|
|
1936
|
+
return true;
|
|
1937
|
+
}
|
|
1938
|
+
pending.resolve(response.result);
|
|
1939
|
+
return true;
|
|
1940
|
+
}
|
|
1941
|
+
handleRpcNotification(notification) {
|
|
1942
|
+
const callback = this.notificationCallbacks.get(notification.id);
|
|
1943
|
+
if (callback) {
|
|
1944
|
+
callback(notification.payload);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
|
|
1949
|
+
// src/storage/MockStorageApi.ts
|
|
1950
|
+
function createMockStorageApi(storageType, appUrl) {
|
|
1951
|
+
const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
|
|
1952
|
+
let prefix;
|
|
1953
|
+
let syncDelay = 0;
|
|
1954
|
+
switch (storageType) {
|
|
1955
|
+
case "deviceCache":
|
|
1956
|
+
prefix = "venus:app";
|
|
1957
|
+
syncDelay = 0;
|
|
1958
|
+
break;
|
|
1959
|
+
case "appStorage":
|
|
1960
|
+
prefix = "venus:app";
|
|
1961
|
+
syncDelay = 100;
|
|
1962
|
+
break;
|
|
1963
|
+
case "globalStorage":
|
|
1964
|
+
prefix = "venus:global";
|
|
1965
|
+
syncDelay = 100;
|
|
1966
|
+
break;
|
|
1967
|
+
default:
|
|
1968
|
+
throw new Error(`Unknown storage type: ${storageType}`);
|
|
1969
|
+
}
|
|
1970
|
+
prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
|
|
1971
|
+
return new MockStorageApi(prefix, syncDelay);
|
|
1972
|
+
}
|
|
1973
|
+
var MockStorageApi = class {
|
|
1974
|
+
constructor(prefix, syncDelay) {
|
|
1975
|
+
__publicField(this, "prefix");
|
|
1976
|
+
__publicField(this, "syncDelay");
|
|
1977
|
+
this.prefix = prefix;
|
|
1978
|
+
this.syncDelay = syncDelay;
|
|
1979
|
+
}
|
|
1980
|
+
async clear() {
|
|
1981
|
+
const fullLength = localStorage.length;
|
|
1982
|
+
for (let i = 0; i < fullLength; i++) {
|
|
1983
|
+
const fullKey = localStorage.key(i);
|
|
1984
|
+
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
1985
|
+
localStorage.removeItem(fullKey);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
await this.simulateSyncDelay();
|
|
1989
|
+
}
|
|
1990
|
+
async getAllItems() {
|
|
1991
|
+
const items = new Array();
|
|
1992
|
+
const fullLength = localStorage.length;
|
|
1993
|
+
for (let i = 0; i < fullLength; i++) {
|
|
1994
|
+
const fullKey = localStorage.key(i);
|
|
1995
|
+
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
1996
|
+
const item = localStorage.getItem(fullKey);
|
|
1997
|
+
if (item) {
|
|
1998
|
+
items.push(item);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
return items;
|
|
2003
|
+
}
|
|
2004
|
+
async getItem(key) {
|
|
2005
|
+
const fullKey = this.buildKey(key);
|
|
2006
|
+
await this.simulateSyncDelay();
|
|
2007
|
+
return localStorage.getItem(fullKey);
|
|
2008
|
+
}
|
|
2009
|
+
async key(index) {
|
|
2010
|
+
const keys = this.keys();
|
|
2011
|
+
if (index < 0 || index >= keys.length) {
|
|
2012
|
+
return null;
|
|
2013
|
+
}
|
|
2014
|
+
await this.simulateSyncDelay();
|
|
2015
|
+
return keys[index];
|
|
2016
|
+
}
|
|
2017
|
+
async length() {
|
|
2018
|
+
return this.keys().length;
|
|
2019
|
+
}
|
|
2020
|
+
async removeItem(key) {
|
|
2021
|
+
const fullKey = this.buildKey(key);
|
|
2022
|
+
await this.simulateSyncDelay();
|
|
2023
|
+
localStorage.removeItem(fullKey);
|
|
2024
|
+
}
|
|
2025
|
+
async setItem(key, item) {
|
|
2026
|
+
const fullKey = this.buildKey(key);
|
|
2027
|
+
await this.simulateSyncDelay();
|
|
2028
|
+
localStorage.setItem(fullKey, item);
|
|
2029
|
+
}
|
|
2030
|
+
async setMultipleItems(entries) {
|
|
2031
|
+
for (const entry of entries) {
|
|
2032
|
+
const fullKey = this.buildKey(entry.key);
|
|
2033
|
+
localStorage.setItem(fullKey, entry.value);
|
|
2034
|
+
}
|
|
2035
|
+
await this.simulateSyncDelay();
|
|
2036
|
+
}
|
|
2037
|
+
async removeMultipleItems(keys) {
|
|
2038
|
+
for (const key of keys) {
|
|
2039
|
+
const fullKey = this.buildKey(key);
|
|
2040
|
+
localStorage.removeItem(fullKey);
|
|
2041
|
+
}
|
|
2042
|
+
await this.simulateSyncDelay();
|
|
2043
|
+
}
|
|
2044
|
+
buildKey(key) {
|
|
2045
|
+
const prefix = this.prefix;
|
|
2046
|
+
return `${prefix}${key}`;
|
|
2047
|
+
}
|
|
2048
|
+
extractKey(fullKey) {
|
|
2049
|
+
const prefix = this.prefix;
|
|
2050
|
+
return fullKey.substring(prefix.length);
|
|
2051
|
+
}
|
|
2052
|
+
keys() {
|
|
2053
|
+
const keys = new Array();
|
|
2054
|
+
let length = localStorage.length;
|
|
2055
|
+
for (let i = 0; i < length; i++) {
|
|
2056
|
+
const fullKey = localStorage.key(i);
|
|
2057
|
+
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2058
|
+
length++;
|
|
2059
|
+
const key = this.extractKey(fullKey);
|
|
2060
|
+
keys.push(key);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
return keys;
|
|
2064
|
+
}
|
|
2065
|
+
async simulateSyncDelay() {
|
|
2066
|
+
const syncDelay = this.syncDelay;
|
|
2067
|
+
if (syncDelay > 0) {
|
|
2068
|
+
await new Promise((resolve) => setTimeout(resolve, syncDelay));
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
};
|
|
2072
|
+
function generateAppIdentifier(appUrl) {
|
|
2073
|
+
if (!appUrl) appUrl = "";
|
|
2074
|
+
const normalizedId = normalizeAppIdentifier(appUrl);
|
|
2075
|
+
let hash = 0;
|
|
2076
|
+
for (let i = 0; i < normalizedId.length; i++) {
|
|
2077
|
+
const char = normalizedId.charCodeAt(i);
|
|
2078
|
+
hash = (hash << 5) - hash + char;
|
|
2079
|
+
hash |= 0;
|
|
2080
|
+
}
|
|
2081
|
+
return Math.abs(hash).toString(16);
|
|
2082
|
+
}
|
|
2083
|
+
function normalizeAppIdentifier(input) {
|
|
2084
|
+
if (input.startsWith("http")) {
|
|
2085
|
+
try {
|
|
2086
|
+
const url = new URL(input);
|
|
2087
|
+
const pathParts = url.pathname.split("/");
|
|
2088
|
+
const h5Index = pathParts.findIndex((part) => part === "H5");
|
|
2089
|
+
if (h5Index !== -1 && h5Index < pathParts.length - 1) {
|
|
2090
|
+
const appId = pathParts[h5Index + 1];
|
|
2091
|
+
return appId;
|
|
2092
|
+
}
|
|
2093
|
+
return url.hostname;
|
|
2094
|
+
} catch (error) {
|
|
2095
|
+
console.error(`[Venus Mock] Error parsing URL: ${error}`, { input });
|
|
2096
|
+
return input;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
if (input.includes("/H5/")) {
|
|
2100
|
+
try {
|
|
2101
|
+
const pathParts = input.split("/");
|
|
2102
|
+
const h5Index = pathParts.findIndex((part) => part === "H5");
|
|
2103
|
+
if (h5Index !== -1 && h5Index < pathParts.length - 1) {
|
|
2104
|
+
const appId = pathParts[h5Index + 1];
|
|
2105
|
+
return appId;
|
|
2106
|
+
}
|
|
2107
|
+
} catch (error) {
|
|
2108
|
+
console.error(`[Venus Mock] Error parsing path-based URL: ${error}`, {
|
|
2109
|
+
input
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
return input;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
// src/storage/RpcStorageApi.ts
|
|
2117
|
+
var RpcStorageApi = class {
|
|
2118
|
+
constructor(rpcClient, methodIds) {
|
|
2119
|
+
__publicField(this, "rpcClient");
|
|
2120
|
+
__publicField(this, "methodIds");
|
|
2121
|
+
this.rpcClient = rpcClient;
|
|
2122
|
+
this.methodIds = methodIds;
|
|
2123
|
+
}
|
|
2124
|
+
clear() {
|
|
2125
|
+
return this.rpcClient.call(this.methodIds.clear);
|
|
2126
|
+
}
|
|
2127
|
+
getItem(key) {
|
|
2128
|
+
return this.rpcClient.call(this.methodIds.getItem, {
|
|
2129
|
+
key
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
setItem(key, value) {
|
|
2133
|
+
return this.rpcClient.call(this.methodIds.setItem, {
|
|
2134
|
+
key,
|
|
2135
|
+
value
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
key(index) {
|
|
2139
|
+
return this.rpcClient.call(this.methodIds.getKey, {
|
|
2140
|
+
index
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
length() {
|
|
2144
|
+
return this.rpcClient.call(this.methodIds.length);
|
|
2145
|
+
}
|
|
2146
|
+
removeItem(key) {
|
|
2147
|
+
return this.rpcClient.call(this.methodIds.removeItem, {
|
|
2148
|
+
key
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
removeMultipleItems(keys) {
|
|
2152
|
+
if (!this.methodIds.removeMultipleItems) {
|
|
2153
|
+
throw new Error("Method not implemented");
|
|
2154
|
+
}
|
|
2155
|
+
return this.rpcClient.call(this.methodIds.removeMultipleItems, {
|
|
2156
|
+
keys
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
getAllItems() {
|
|
2160
|
+
if (!this.methodIds.getAllItems) {
|
|
2161
|
+
throw new Error("Method not implemented");
|
|
2162
|
+
}
|
|
2163
|
+
return this.rpcClient.call(this.methodIds.getAllItems);
|
|
2164
|
+
}
|
|
2165
|
+
setMultipleItems(items) {
|
|
2166
|
+
if (!this.methodIds.setMultipleItems) {
|
|
2167
|
+
throw new Error("Method not implemented");
|
|
2168
|
+
}
|
|
2169
|
+
return this.rpcClient.call(this.methodIds.setMultipleItems, {
|
|
2170
|
+
items
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
};
|
|
2174
|
+
|
|
2175
|
+
// src/storage/index.ts
|
|
2176
|
+
function initializeStorage(venusApiInstance, host) {
|
|
2177
|
+
venusApiInstance.deviceCache = host.deviceCache;
|
|
2178
|
+
venusApiInstance.appStorage = host.appStorage;
|
|
2179
|
+
venusApiInstance.globalStorage = host.globalStorage;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// src/simulation/utils.ts
|
|
2183
|
+
function sumContributions(contributions) {
|
|
2184
|
+
const totals = {};
|
|
2185
|
+
for (const profileId in contributions) {
|
|
2186
|
+
for (const entityId in contributions[profileId]) {
|
|
2187
|
+
const amount = contributions[profileId][entityId] || 0;
|
|
2188
|
+
totals[entityId] = (totals[entityId] || 0) + amount;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
return totals;
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
// src/simulation/RpcSimulationApi.ts
|
|
2195
|
+
var RpcSimulationApi = class {
|
|
2196
|
+
constructor(rpcClient) {
|
|
2197
|
+
__publicField(this, "rpcClient");
|
|
2198
|
+
__publicField(this, "_simulationConfig", null);
|
|
2199
|
+
this.rpcClient = rpcClient;
|
|
2200
|
+
}
|
|
2201
|
+
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2202
|
+
return this.rpcClient.call(
|
|
2203
|
+
"H5_SIMULATION_VALIDATE_ASSIGNMENT" /* H5_SIMULATION_VALIDATE_ASSIGNMENT */,
|
|
2204
|
+
{
|
|
2205
|
+
containerId,
|
|
2206
|
+
slotId,
|
|
2207
|
+
itemId
|
|
2208
|
+
}
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
sumContributions(contributions) {
|
|
2212
|
+
return sumContributions(contributions);
|
|
2213
|
+
}
|
|
2214
|
+
executeBatchOperationsAsync(operations, validateOnly) {
|
|
2215
|
+
return this.rpcClient.call("H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */, {
|
|
2216
|
+
operations,
|
|
2217
|
+
validateOnly
|
|
2218
|
+
});
|
|
2219
|
+
}
|
|
2220
|
+
async getAvailableItemsAsync(containerId, slotId) {
|
|
2221
|
+
const response = await this.rpcClient.call(
|
|
2222
|
+
"H5_SIMULATION_GET_AVAILABLE_ITEMS" /* H5_SIMULATION_GET_AVAILABLE_ITEMS */,
|
|
2223
|
+
{
|
|
2224
|
+
containerId,
|
|
2225
|
+
slotId
|
|
2226
|
+
}
|
|
2227
|
+
);
|
|
2228
|
+
return response.availableItems || [];
|
|
2229
|
+
}
|
|
2230
|
+
calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
|
|
2231
|
+
return this.rpcClient.call(
|
|
2232
|
+
"H5_SIMULATION_CALCULATE_POWER_PREVIEW" /* H5_SIMULATION_CALCULATE_POWER_PREVIEW */,
|
|
2233
|
+
{
|
|
2234
|
+
containerId,
|
|
2235
|
+
slotId,
|
|
2236
|
+
candidateItemId
|
|
2237
|
+
}
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
2241
|
+
return this.rpcClient.call("H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */, {
|
|
2242
|
+
containerId,
|
|
2243
|
+
slotId,
|
|
2244
|
+
itemId
|
|
2245
|
+
});
|
|
2246
|
+
}
|
|
2247
|
+
removeItemFromSlotAsync(containerId, slotId) {
|
|
2248
|
+
return this.rpcClient.call("H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */, {
|
|
2249
|
+
containerId,
|
|
2250
|
+
slotId
|
|
2251
|
+
});
|
|
2252
|
+
}
|
|
2253
|
+
async getSlotContainersAsync() {
|
|
2254
|
+
const response = await this.rpcClient.call(
|
|
2255
|
+
"H5_SIMULATION_GET_CONTAINERS" /* H5_SIMULATION_GET_CONTAINERS */,
|
|
2256
|
+
{}
|
|
2257
|
+
);
|
|
2258
|
+
return response.containers || [];
|
|
2259
|
+
}
|
|
2260
|
+
async getSlotAssignmentsAsync(containerId) {
|
|
2261
|
+
const response = await this.rpcClient.call(
|
|
2262
|
+
"H5_SIMULATION_GET_ASSIGNMENTS" /* H5_SIMULATION_GET_ASSIGNMENTS */,
|
|
2263
|
+
{
|
|
2264
|
+
containerId
|
|
2265
|
+
}
|
|
2266
|
+
);
|
|
2267
|
+
return Array.isArray(response) ? response : response.assignments || [];
|
|
2268
|
+
}
|
|
2269
|
+
async getStateAsync(roomId) {
|
|
2270
|
+
const response = await this.rpcClient.call(
|
|
2271
|
+
"H5_SIMULATION_GET_STATE" /* H5_SIMULATION_GET_STATE */,
|
|
2272
|
+
{
|
|
2273
|
+
roomId
|
|
2274
|
+
}
|
|
2275
|
+
);
|
|
2276
|
+
console.log("[Venus SDK] getStateAsync", response);
|
|
2277
|
+
if (response.configuration) {
|
|
2278
|
+
this._simulationConfig = response.configuration;
|
|
2279
|
+
}
|
|
2280
|
+
return response;
|
|
2281
|
+
}
|
|
2282
|
+
async getConfigAsync(roomId) {
|
|
2283
|
+
if (this._simulationConfig) {
|
|
2284
|
+
return this._simulationConfig;
|
|
2285
|
+
}
|
|
2286
|
+
const config = await this.rpcClient.call(
|
|
2287
|
+
"H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
|
|
2288
|
+
{}
|
|
2289
|
+
);
|
|
2290
|
+
console.log("[Venus SDK] getConfigAsync", config);
|
|
2291
|
+
if (config) {
|
|
2292
|
+
this._simulationConfig = config;
|
|
2293
|
+
return config;
|
|
2294
|
+
}
|
|
2295
|
+
throw new Error("No simulation configuration available");
|
|
2296
|
+
}
|
|
2297
|
+
executeRecipeAsync(recipeId, inputs, options) {
|
|
2298
|
+
return this.rpcClient.call("H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */, {
|
|
2299
|
+
recipeId,
|
|
2300
|
+
inputs,
|
|
2301
|
+
roomId: options?.roomId,
|
|
2302
|
+
batchAmount: options?.batchAmount,
|
|
2303
|
+
allowPartialBatch: options?.allowPartialBatch,
|
|
2304
|
+
entity: options?.entity
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
collectRecipeAsync(runId) {
|
|
2308
|
+
return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
|
|
2309
|
+
runId
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
getActiveRunsAsync(options) {
|
|
2313
|
+
return this.rpcClient.call("H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */, {
|
|
2314
|
+
roomId: options?.roomId
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2318
|
+
return this.rpcClient.call(
|
|
2319
|
+
"H5_SIMULATION_EXECUTE_SCOPED_RECIPE" /* H5_SIMULATION_EXECUTE_SCOPED_RECIPE */,
|
|
2320
|
+
{
|
|
2321
|
+
recipeId,
|
|
2322
|
+
entity,
|
|
2323
|
+
inputs,
|
|
2324
|
+
roomId: options?.roomId ?? null,
|
|
2325
|
+
options
|
|
2326
|
+
}
|
|
2327
|
+
);
|
|
2328
|
+
}
|
|
2329
|
+
getAvailableRecipesAsync(options) {
|
|
2330
|
+
return this.rpcClient.call(
|
|
2331
|
+
"H5_SIMULATION_GET_AVAILABLE_RECIPES" /* H5_SIMULATION_GET_AVAILABLE_RECIPES */,
|
|
2332
|
+
{
|
|
2333
|
+
roomId: options?.roomId || null,
|
|
2334
|
+
includeActorRecipes: options?.includeActorRecipes || false
|
|
2335
|
+
}
|
|
2336
|
+
);
|
|
2337
|
+
}
|
|
2338
|
+
getRecipeRequirementsAsync(recipe) {
|
|
2339
|
+
return this.rpcClient.call(
|
|
2340
|
+
"H5_SIMULATION_GET_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_RECIPE_REQUIREMENTS */,
|
|
2341
|
+
{
|
|
2342
|
+
recipeId: recipe.recipeId,
|
|
2343
|
+
entity: recipe.entity,
|
|
2344
|
+
batchAmount: recipe.batchAmount
|
|
2345
|
+
}
|
|
2346
|
+
);
|
|
2347
|
+
}
|
|
2348
|
+
getBatchRecipeRequirementsAsync(recipes) {
|
|
2349
|
+
return this.rpcClient.call(
|
|
2350
|
+
"H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS" /* H5_SIMULATION_GET_BATCH_RECIPE_REQUIREMENTS */,
|
|
2351
|
+
{
|
|
2352
|
+
recipes
|
|
2353
|
+
}
|
|
2354
|
+
);
|
|
2355
|
+
}
|
|
2356
|
+
triggerRecipeChainAsync(recipeId, options) {
|
|
2357
|
+
return this.rpcClient.call(
|
|
2358
|
+
"H5_SIMULATION_TRIGGER_RECIPE_CHAIN" /* H5_SIMULATION_TRIGGER_RECIPE_CHAIN */,
|
|
2359
|
+
{
|
|
2360
|
+
triggerRecipeId: recipeId,
|
|
2361
|
+
context: options?.context,
|
|
2362
|
+
roomId: options?.roomId
|
|
2363
|
+
}
|
|
2364
|
+
);
|
|
2365
|
+
}
|
|
2366
|
+
getEntityMetadataAsync(entityId) {
|
|
2367
|
+
return this.rpcClient.call(
|
|
2368
|
+
"H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
|
|
2369
|
+
{
|
|
2370
|
+
entityId
|
|
2371
|
+
}
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2375
|
+
const response = await this.rpcClient.call(
|
|
2376
|
+
"H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
|
|
2377
|
+
{
|
|
2378
|
+
entityId,
|
|
2379
|
+
fieldPath,
|
|
2380
|
+
entity
|
|
2381
|
+
}
|
|
2382
|
+
);
|
|
2383
|
+
return response.value;
|
|
2384
|
+
}
|
|
2385
|
+
};
|
|
2386
|
+
|
|
2387
|
+
// src/simulation/MockSimulationApi.ts
|
|
2388
|
+
function generateAppIdentifier2() {
|
|
2389
|
+
if (typeof window === "undefined") return "unknown-app";
|
|
2390
|
+
const url = window.location.href;
|
|
2391
|
+
const match = url.match(/\/H5\/([^\/]+)/);
|
|
2392
|
+
return match ? match[1] : "unknown-app";
|
|
2393
|
+
}
|
|
2394
|
+
var MockSimulationApi = class {
|
|
2395
|
+
constructor(simulationConfig = null) {
|
|
2396
|
+
__publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
|
|
2397
|
+
// appIdentifier -> config
|
|
2398
|
+
__publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
|
|
2399
|
+
// appIdentifier -> config
|
|
2400
|
+
__publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
|
|
2401
|
+
// appIdentifier -> timers[]
|
|
2402
|
+
__publicField(this, "appId");
|
|
2403
|
+
__publicField(this, "providedSimulationConfig");
|
|
2404
|
+
this.appId = generateAppIdentifier2();
|
|
2405
|
+
this.providedSimulationConfig = simulationConfig;
|
|
2406
|
+
}
|
|
2407
|
+
sumContributions(contributions) {
|
|
2408
|
+
return sumContributions(contributions);
|
|
2409
|
+
}
|
|
2410
|
+
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2411
|
+
this.log("validateSlotAssignmentAsync called:", {
|
|
2412
|
+
containerId,
|
|
2413
|
+
slotId,
|
|
2414
|
+
itemId
|
|
2415
|
+
});
|
|
2416
|
+
return { valid: true, message: "Mock validation successful" };
|
|
2417
|
+
}
|
|
2418
|
+
async executeBatchOperationsAsync(operations, validateOnly) {
|
|
2419
|
+
this.log("executeBatchOperationsAsync called:", {
|
|
2420
|
+
operations,
|
|
2421
|
+
validateOnly
|
|
2422
|
+
});
|
|
2423
|
+
return {
|
|
2424
|
+
success: true,
|
|
2425
|
+
results: operations.map(() => ({ success: true }))
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
async getAvailableItemsAsync(containerId, slotId) {
|
|
2429
|
+
console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
|
|
2430
|
+
containerId,
|
|
2431
|
+
slotId
|
|
2432
|
+
});
|
|
2433
|
+
const appIdentifier = generateAppIdentifier2();
|
|
2434
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2435
|
+
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2436
|
+
entities: {}
|
|
2437
|
+
};
|
|
2438
|
+
const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
|
|
2439
|
+
entityId,
|
|
2440
|
+
quantity: 1,
|
|
2441
|
+
metadata: entity.metadata,
|
|
2442
|
+
powerPreview: 100
|
|
2443
|
+
// Mock power value
|
|
2444
|
+
}));
|
|
2445
|
+
return availableItems;
|
|
2446
|
+
}
|
|
2447
|
+
async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
|
|
2448
|
+
this.log("calculatePowerPreviewAsync called:", {
|
|
2449
|
+
containerId,
|
|
2450
|
+
slotId,
|
|
2451
|
+
candidateItemId
|
|
2452
|
+
});
|
|
2453
|
+
return {
|
|
2454
|
+
currentPower: 1e3,
|
|
2455
|
+
previewPower: 1200,
|
|
2456
|
+
powerDelta: 200,
|
|
2457
|
+
breakdown: { base: 800, weapon: 200, armor: 200 }
|
|
2458
|
+
};
|
|
2459
|
+
}
|
|
2460
|
+
async getSlotContainersAsync() {
|
|
2461
|
+
this.log("getSlotContainersAsync called");
|
|
2462
|
+
const appIdentifier = this.appId;
|
|
2463
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2464
|
+
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2465
|
+
entities: {}
|
|
2466
|
+
};
|
|
2467
|
+
const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
|
|
2468
|
+
entityId,
|
|
2469
|
+
slots: entity.metadata?.slots,
|
|
2470
|
+
isOwned: true
|
|
2471
|
+
// Mock: assume all containers are owned
|
|
2472
|
+
}));
|
|
2473
|
+
return containers;
|
|
2474
|
+
}
|
|
2475
|
+
async getSlotAssignmentsAsync(containerId) {
|
|
2476
|
+
this.log("getSlotAssignmentsAsync called for:", containerId);
|
|
2477
|
+
return [];
|
|
2478
|
+
}
|
|
2479
|
+
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2480
|
+
this.log("resolveFieldValueAsync called:", {
|
|
2481
|
+
entityId,
|
|
2482
|
+
fieldPath,
|
|
2483
|
+
entity
|
|
2484
|
+
});
|
|
2485
|
+
const mockValues = {
|
|
2486
|
+
basePower: 850,
|
|
2487
|
+
weaponPower: 300,
|
|
2488
|
+
armorPower: 150,
|
|
2489
|
+
total_power: 1300,
|
|
2490
|
+
total_defense_power: 5e3
|
|
2491
|
+
};
|
|
2492
|
+
return mockValues[fieldPath] || 100;
|
|
2493
|
+
}
|
|
2494
|
+
async getEntityMetadataAsync(entityId) {
|
|
2495
|
+
this.log("getEntityMetadataAsync called for:", entityId);
|
|
2496
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2497
|
+
const appIdentifier = this.appId;
|
|
2498
|
+
const config = mockSimulationConfigs.get(
|
|
2499
|
+
appIdentifier
|
|
2500
|
+
) || {
|
|
2501
|
+
entities: {}};
|
|
2502
|
+
const entity = config.entities[entityId];
|
|
2503
|
+
return entity?.metadata || {};
|
|
2504
|
+
}
|
|
2505
|
+
async collectRecipeAsync(runId) {
|
|
2506
|
+
this.log("collectRecipeAsync called:", { runId });
|
|
2507
|
+
const mockRewards = {
|
|
2508
|
+
cash: Math.floor(Math.random() * 1e3) + 500,
|
|
2509
|
+
experience: Math.floor(Math.random() * 50) + 25
|
|
2510
|
+
};
|
|
2511
|
+
return {
|
|
2512
|
+
success: true,
|
|
2513
|
+
runId,
|
|
2514
|
+
rewards: mockRewards,
|
|
2515
|
+
message: "Rewards collected successfully"
|
|
2516
|
+
};
|
|
2517
|
+
}
|
|
2518
|
+
executeRecipeAsync(recipeId, inputs, options) {
|
|
2519
|
+
this.log("executeRecipeAsync called:", {
|
|
2520
|
+
recipeId,
|
|
2521
|
+
inputs,
|
|
2522
|
+
options
|
|
2523
|
+
});
|
|
2524
|
+
const appIdentifier = this.appId;
|
|
2525
|
+
return this.executeRecipe(appIdentifier, recipeId, inputs);
|
|
2526
|
+
}
|
|
2527
|
+
async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2528
|
+
this.log("executeScopedRecipeAsync called:", {
|
|
2529
|
+
recipeId,
|
|
2530
|
+
entity,
|
|
2531
|
+
inputs,
|
|
2532
|
+
roomId: options?.roomId,
|
|
2533
|
+
options
|
|
2534
|
+
});
|
|
2535
|
+
return {
|
|
2536
|
+
success: true,
|
|
2537
|
+
message: "Mock scoped recipe execution successful"
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
async getActiveRunsAsync(options) {
|
|
2541
|
+
this.log("getActiveRunsAsync called:", options);
|
|
2542
|
+
const appIdentifier = this.appId;
|
|
2543
|
+
let state = this.mockSimulationStates.get(appIdentifier);
|
|
2544
|
+
if (!state) {
|
|
2545
|
+
state = await this.initializeSimulationState(appIdentifier);
|
|
2546
|
+
}
|
|
2547
|
+
return state.activeRuns || [];
|
|
2548
|
+
}
|
|
2549
|
+
async getAvailableRecipesAsync(options) {
|
|
2550
|
+
this.log("getAvailableRecipesAsync called:", options);
|
|
2551
|
+
const baseRecipes = [
|
|
2552
|
+
{ id: "collect_resources", scope: "player", clientViewable: true },
|
|
2553
|
+
{ id: "upgrade_equipment", scope: "player", clientViewable: true }
|
|
2554
|
+
];
|
|
2555
|
+
if (options?.roomId) {
|
|
2556
|
+
baseRecipes.push(
|
|
2557
|
+
{ id: "room_upgrade", scope: "room", clientViewable: true },
|
|
2558
|
+
{ id: "cooperative_project", scope: "room", clientViewable: true }
|
|
2559
|
+
);
|
|
2560
|
+
}
|
|
2561
|
+
if (options?.includeActorRecipes && options?.roomId) {
|
|
2562
|
+
baseRecipes.push(
|
|
2563
|
+
{ id: "trade_with_npc", scope: "actor", clientViewable: true },
|
|
2564
|
+
{ id: "attack_monster", scope: "actor", clientViewable: true }
|
|
2565
|
+
);
|
|
2566
|
+
}
|
|
2567
|
+
return { success: true, recipes: baseRecipes };
|
|
2568
|
+
}
|
|
2569
|
+
async getBatchRecipeRequirementsAsync(recipes) {
|
|
2570
|
+
this.log("getBatchRecipeRequirementsAsync called:", {
|
|
2571
|
+
count: recipes?.length
|
|
2572
|
+
});
|
|
2573
|
+
const results = (recipes || []).map((q) => ({
|
|
2574
|
+
recipeId: q.recipeId,
|
|
2575
|
+
entity: q.entity || null,
|
|
2576
|
+
amount: q.batchAmount || 1,
|
|
2577
|
+
inputs: { cash: "BE:0" },
|
|
2578
|
+
canAfford: true,
|
|
2579
|
+
disabled: false
|
|
2580
|
+
}));
|
|
2581
|
+
return { success: true, results };
|
|
2582
|
+
}
|
|
2583
|
+
async getRecipeRequirementsAsync(recipe) {
|
|
2584
|
+
this.log("getRecipeRequirementsAsync called:", recipe);
|
|
2585
|
+
return {
|
|
2586
|
+
recipeId: recipe.recipeId,
|
|
2587
|
+
entity: recipe.entity || null,
|
|
2588
|
+
amount: recipe.batchAmount,
|
|
2589
|
+
inputs: { cash: "BE:0" },
|
|
2590
|
+
canAfford: true,
|
|
2591
|
+
disabled: false
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
async triggerRecipeChainAsync(recipeId, options) {
|
|
2595
|
+
this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
|
|
2596
|
+
return {
|
|
2597
|
+
success: true,
|
|
2598
|
+
message: "Mock recipe chain triggered successfully"
|
|
2599
|
+
};
|
|
2600
|
+
}
|
|
2601
|
+
log(message, ...args) {
|
|
2602
|
+
console.log(`[Venus Sim Mock] ${message}`, args);
|
|
2603
|
+
}
|
|
2604
|
+
async executeRecipe(appIdentifier, recipeId, inputs) {
|
|
2605
|
+
this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
|
|
2606
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2607
|
+
const mockSimulationStates = this.mockSimulationStates;
|
|
2608
|
+
let config = mockSimulationConfigs.get(appIdentifier);
|
|
2609
|
+
let state = mockSimulationStates.get(appIdentifier);
|
|
2610
|
+
if (!config || !state) {
|
|
2611
|
+
state = await this.initializeSimulationState(appIdentifier);
|
|
2612
|
+
config = mockSimulationConfigs.get(appIdentifier);
|
|
2613
|
+
if (!config) {
|
|
2614
|
+
throw new Error("Failed to initialize simulation config");
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
const recipe = config.recipes?.[recipeId];
|
|
2618
|
+
if (!recipe) {
|
|
2619
|
+
throw new Error(`Recipe ${recipeId} not found`);
|
|
2620
|
+
}
|
|
2621
|
+
if (state.disabledRecipes?.includes(recipeId)) {
|
|
2622
|
+
throw new Error(`Recipe ${recipeId} is disabled`);
|
|
2623
|
+
}
|
|
2624
|
+
if (recipe.inputs) {
|
|
2625
|
+
for (const [entityId, required] of Object.entries(recipe.inputs)) {
|
|
2626
|
+
const available = state.inventory[entityId] || 0;
|
|
2627
|
+
if (available < required) {
|
|
2628
|
+
throw new Error(
|
|
2629
|
+
`Insufficient ${entityId}: required ${required}, available ${available}`
|
|
2630
|
+
);
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
if (recipe.inputs) {
|
|
2635
|
+
for (const [entityId, input] of Object.entries(recipe.inputs)) {
|
|
2636
|
+
const inventoryValue = state.inventory[entityId] || 0;
|
|
2637
|
+
if (typeof input === "number" && typeof inventoryValue === "number") {
|
|
2638
|
+
state.inventory[entityId] = inventoryValue - input;
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
if (recipe.beginEffects) {
|
|
2643
|
+
this.applyEffects(state, recipe.beginEffects);
|
|
2644
|
+
}
|
|
2645
|
+
const runId = this.generateRunId();
|
|
2646
|
+
const now = Date.now();
|
|
2647
|
+
const expiresAt = now + (recipe.duration || 0);
|
|
2648
|
+
const run = {
|
|
2649
|
+
id: runId,
|
|
2650
|
+
recipeId,
|
|
2651
|
+
status: "running",
|
|
2652
|
+
startTime: now,
|
|
2653
|
+
expiresAt,
|
|
2654
|
+
inputs: recipe.inputs || {}
|
|
2655
|
+
};
|
|
2656
|
+
state.activeRuns.push(run);
|
|
2657
|
+
if (recipe.duration === 0) {
|
|
2658
|
+
this.completeRun(appIdentifier, runId);
|
|
2659
|
+
return { status: "completed", runId };
|
|
2660
|
+
} else {
|
|
2661
|
+
const mockActiveTimers = this.mockActiveTimers;
|
|
2662
|
+
const timer = setTimeout(() => {
|
|
2663
|
+
this.completeRun(appIdentifier, runId);
|
|
2664
|
+
}, recipe.duration);
|
|
2665
|
+
const timers = mockActiveTimers.get(appIdentifier) || [];
|
|
2666
|
+
timers.push(timer);
|
|
2667
|
+
mockActiveTimers.set(appIdentifier, timers);
|
|
2668
|
+
return {
|
|
2669
|
+
status: "running",
|
|
2670
|
+
runId,
|
|
2671
|
+
expiresAt: new Date(expiresAt).toISOString()
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
async initializeSimulationState(appIdentifier) {
|
|
2676
|
+
this.log(`Initializing simulation state for ${appIdentifier}`);
|
|
2677
|
+
const providedSimulationConfig = this.providedSimulationConfig;
|
|
2678
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2679
|
+
const mockSimulationStates = this.mockSimulationStates;
|
|
2680
|
+
const mockActiveTimers = this.mockActiveTimers;
|
|
2681
|
+
const config = providedSimulationConfig || {
|
|
2682
|
+
version: "1.0",
|
|
2683
|
+
entities: {},
|
|
2684
|
+
recipes: {}
|
|
2685
|
+
};
|
|
2686
|
+
mockSimulationConfigs.set(appIdentifier, config);
|
|
2687
|
+
const initialInventory = {};
|
|
2688
|
+
if (providedSimulationConfig && config.entities) {
|
|
2689
|
+
Object.keys(config.entities).forEach((entityId) => {
|
|
2690
|
+
initialInventory[entityId] = 0;
|
|
2691
|
+
});
|
|
2692
|
+
}
|
|
2693
|
+
const state = {
|
|
2694
|
+
inventory: initialInventory,
|
|
2695
|
+
activeRuns: [],
|
|
2696
|
+
disabledRecipes: new Array()
|
|
2697
|
+
};
|
|
2698
|
+
if (config.recipes) {
|
|
2699
|
+
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
2700
|
+
if (recipe.metadata?.startsDisabled) {
|
|
2701
|
+
state.disabledRecipes.push(recipeId);
|
|
2702
|
+
}
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
mockSimulationStates.set(appIdentifier, state);
|
|
2706
|
+
mockActiveTimers.set(appIdentifier, []);
|
|
2707
|
+
console.log(
|
|
2708
|
+
`[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
|
|
2709
|
+
state
|
|
2710
|
+
);
|
|
2711
|
+
if (config.recipes) {
|
|
2712
|
+
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
2713
|
+
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
2714
|
+
if (isAutoRestart && recipe.outputs) {
|
|
2715
|
+
this.log(`Found auto-restart recipe: ${recipeId}`, {
|
|
2716
|
+
topLevelAutoRestart: recipe.autoRestart,
|
|
2717
|
+
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
2718
|
+
hasOutputs: !!recipe.outputs,
|
|
2719
|
+
duration: recipe.duration
|
|
2720
|
+
});
|
|
2721
|
+
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
2722
|
+
if (condition && condition.entity) {
|
|
2723
|
+
const currentAmount = initialInventory[condition.entity] || 0;
|
|
2724
|
+
if (currentAmount < condition.maxValue) {
|
|
2725
|
+
console.log(
|
|
2726
|
+
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
|
|
2727
|
+
{
|
|
2728
|
+
currentAmount,
|
|
2729
|
+
maxValue: condition.maxValue,
|
|
2730
|
+
entity: condition.entity
|
|
2731
|
+
}
|
|
2732
|
+
);
|
|
2733
|
+
setTimeout(() => {
|
|
2734
|
+
this.executeRecipe(appIdentifier, recipeId, {});
|
|
2735
|
+
}, 1e3);
|
|
2736
|
+
}
|
|
2737
|
+
} else {
|
|
2738
|
+
console.log(
|
|
2739
|
+
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
|
|
2740
|
+
);
|
|
2741
|
+
setTimeout(() => {
|
|
2742
|
+
this.executeRecipe(appIdentifier, recipeId, {});
|
|
2743
|
+
}, 1e3);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2748
|
+
return state;
|
|
2749
|
+
}
|
|
2750
|
+
generateRunId() {
|
|
2751
|
+
return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
2752
|
+
}
|
|
2753
|
+
completeRun(appIdentifier, runId) {
|
|
2754
|
+
this.log(`Completing run ${runId} for ${appIdentifier}`);
|
|
2755
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2756
|
+
const mockSimulationStates = this.mockSimulationStates;
|
|
2757
|
+
const config = mockSimulationConfigs.get(appIdentifier);
|
|
2758
|
+
const state = mockSimulationStates.get(appIdentifier);
|
|
2759
|
+
if (!config || !state) return;
|
|
2760
|
+
const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
|
|
2761
|
+
if (runIndex === -1) return;
|
|
2762
|
+
const run = state.activeRuns[runIndex];
|
|
2763
|
+
const recipe = config.recipes?.[run.recipeId];
|
|
2764
|
+
if (!recipe) return;
|
|
2765
|
+
const outputs = {};
|
|
2766
|
+
const rng = this.createSeededRandom(runId);
|
|
2767
|
+
if (recipe.outputs) {
|
|
2768
|
+
for (const [entityId, value] of Object.entries(recipe.outputs)) {
|
|
2769
|
+
if (typeof value === "number") {
|
|
2770
|
+
outputs[entityId] = value;
|
|
2771
|
+
} else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
|
|
2772
|
+
outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
for (const [entityId, amount] of Object.entries(outputs)) {
|
|
2777
|
+
state.inventory[entityId] = (state.inventory[entityId] || 0) + amount;
|
|
2778
|
+
}
|
|
2779
|
+
if (recipe.endEffects) {
|
|
2780
|
+
this.applyEffects(state, recipe.endEffects);
|
|
2781
|
+
}
|
|
2782
|
+
run.status = "completed";
|
|
2783
|
+
run.outputs = outputs;
|
|
2784
|
+
state.activeRuns.splice(runIndex, 1);
|
|
2785
|
+
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
2786
|
+
if (isAutoRestart) {
|
|
2787
|
+
console.log(
|
|
2788
|
+
`[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
|
|
2789
|
+
{
|
|
2790
|
+
topLevelAutoRestart: recipe.autoRestart,
|
|
2791
|
+
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
2792
|
+
hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
|
|
2793
|
+
}
|
|
2794
|
+
);
|
|
2795
|
+
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
2796
|
+
if (condition) {
|
|
2797
|
+
const currentAmount = state.inventory[condition.entity] || 0;
|
|
2798
|
+
if (currentAmount < condition.maxValue) {
|
|
2799
|
+
console.log(
|
|
2800
|
+
`[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
|
|
2801
|
+
{
|
|
2802
|
+
currentAmount,
|
|
2803
|
+
maxValue: condition.maxValue,
|
|
2804
|
+
entity: condition.entity
|
|
2805
|
+
}
|
|
2806
|
+
);
|
|
2807
|
+
setTimeout(() => {
|
|
2808
|
+
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
2809
|
+
}, 1e3);
|
|
2810
|
+
}
|
|
2811
|
+
} else {
|
|
2812
|
+
console.log(
|
|
2813
|
+
`[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
|
|
2814
|
+
);
|
|
2815
|
+
setTimeout(() => {
|
|
2816
|
+
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
2817
|
+
}, 1e3);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
console.log(
|
|
2821
|
+
`[Venus Simulation Mock] Completed run ${runId}, outputs:`,
|
|
2822
|
+
outputs
|
|
2823
|
+
);
|
|
2824
|
+
}
|
|
2825
|
+
createSeededRandom(seed) {
|
|
2826
|
+
let hash = 0;
|
|
2827
|
+
for (let i = 0; i < seed.length; i++) {
|
|
2828
|
+
const char = seed.charCodeAt(i);
|
|
2829
|
+
hash = (hash << 5) - hash + char;
|
|
2830
|
+
hash = hash & hash;
|
|
2831
|
+
}
|
|
2832
|
+
return () => {
|
|
2833
|
+
hash = (hash * 9301 + 49297) % 233280;
|
|
2834
|
+
return hash / 233280;
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
applyEffects(state, effects) {
|
|
2838
|
+
if (!effects || !Array.isArray(effects)) return;
|
|
2839
|
+
for (const effect of effects) {
|
|
2840
|
+
switch (effect.type) {
|
|
2841
|
+
case "set":
|
|
2842
|
+
state.inventory[effect.target] = effect.value;
|
|
2843
|
+
console.log(
|
|
2844
|
+
`[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
|
|
2845
|
+
);
|
|
2846
|
+
break;
|
|
2847
|
+
case "add":
|
|
2848
|
+
state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
|
|
2849
|
+
console.log(
|
|
2850
|
+
`[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
|
|
2851
|
+
);
|
|
2852
|
+
break;
|
|
2853
|
+
case "multiply":
|
|
2854
|
+
state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
|
|
2855
|
+
console.log(
|
|
2856
|
+
`[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
2857
|
+
);
|
|
2858
|
+
break;
|
|
2859
|
+
case "min":
|
|
2860
|
+
state.inventory[effect.target] = Math.max(
|
|
2861
|
+
state.inventory[effect.target] || 0,
|
|
2862
|
+
effect.value
|
|
2863
|
+
);
|
|
2864
|
+
console.log(
|
|
2865
|
+
`[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
2866
|
+
);
|
|
2867
|
+
break;
|
|
2868
|
+
case "max":
|
|
2869
|
+
state.inventory[effect.target] = Math.min(
|
|
2870
|
+
state.inventory[effect.target] || 0,
|
|
2871
|
+
effect.value
|
|
2872
|
+
);
|
|
2873
|
+
console.log(
|
|
2874
|
+
`[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
2875
|
+
);
|
|
2876
|
+
break;
|
|
2877
|
+
case "enable_recipe":
|
|
2878
|
+
if (state.disabledRecipes?.includes(effect.target)) {
|
|
2879
|
+
state.disabledRecipes = state.disabledRecipes.filter(
|
|
2880
|
+
(r) => r !== effect.target
|
|
2881
|
+
);
|
|
2882
|
+
console.log(
|
|
2883
|
+
`[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
break;
|
|
2887
|
+
case "disable_recipe":
|
|
2888
|
+
if (!state.disabledRecipes) state.disabledRecipes = [];
|
|
2889
|
+
if (!state.disabledRecipes.includes(effect.target)) {
|
|
2890
|
+
state.disabledRecipes.push(effect.target);
|
|
2891
|
+
console.log(
|
|
2892
|
+
`[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
break;
|
|
2896
|
+
case "trigger_recipe":
|
|
2897
|
+
console.log(
|
|
2898
|
+
`[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
|
|
2899
|
+
);
|
|
2900
|
+
break;
|
|
2901
|
+
default:
|
|
2902
|
+
console.warn(
|
|
2903
|
+
`[Venus Simulation Mock] Unknown effect type: ${effect.type}`
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
async getConfigAsync() {
|
|
2909
|
+
console.log("[Venus Simulation Mock] getConfigAsync called");
|
|
2910
|
+
const appIdentifier = this.appId;
|
|
2911
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2912
|
+
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2913
|
+
version: "1.0",
|
|
2914
|
+
entities: {},
|
|
2915
|
+
recipes: {}
|
|
2916
|
+
};
|
|
2917
|
+
return config;
|
|
2918
|
+
}
|
|
2919
|
+
async getStateAsync(roomId) {
|
|
2920
|
+
this.log("getStateAsync called:", roomId);
|
|
2921
|
+
const appIdentifier = this.appId;
|
|
2922
|
+
const mockSimulationStates = this.mockSimulationStates;
|
|
2923
|
+
let state = mockSimulationStates.get(appIdentifier);
|
|
2924
|
+
if (!state) {
|
|
2925
|
+
state = await this.initializeSimulationState(appIdentifier);
|
|
2926
|
+
}
|
|
2927
|
+
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2928
|
+
return {
|
|
2929
|
+
...state,
|
|
2930
|
+
roomId,
|
|
2931
|
+
configuration: mockSimulationConfigs.get(appIdentifier)
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
async assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
2935
|
+
this.log("assignItemToSlotAsync called:", {
|
|
2936
|
+
containerId,
|
|
2937
|
+
slotId,
|
|
2938
|
+
itemId
|
|
2939
|
+
});
|
|
2940
|
+
return { success: true, message: "Mock assignment successful" };
|
|
2941
|
+
}
|
|
2942
|
+
async removeItemFromSlotAsync(containerId, slotId) {
|
|
2943
|
+
this.log("removeItemFromSlotAsync called:", {
|
|
2944
|
+
containerId,
|
|
2945
|
+
slotId
|
|
2946
|
+
});
|
|
2947
|
+
return { success: true, message: "Mock removal successful" };
|
|
2948
|
+
}
|
|
2949
|
+
};
|
|
2950
|
+
|
|
2951
|
+
// src/simulation/index.ts
|
|
2952
|
+
function initializeSimulation(venusApi, host) {
|
|
2953
|
+
console.log("[Venus SDK] Initializing new Simulation Api");
|
|
2954
|
+
venusApi.simulation = {
|
|
2955
|
+
isEnabled: () => true
|
|
2956
|
+
};
|
|
2957
|
+
venusApi.simulation.getConfigAsync = () => {
|
|
2958
|
+
return host.simulation.getConfigAsync();
|
|
2959
|
+
};
|
|
2960
|
+
venusApi.simulation.getStateAsync = (options) => {
|
|
2961
|
+
return host.simulation.getStateAsync(options?.roomId);
|
|
2962
|
+
};
|
|
2963
|
+
venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
|
|
2964
|
+
return host.simulation.executeRecipeAsync(recipeId, inputs, options);
|
|
2965
|
+
};
|
|
2966
|
+
venusApi.simulation.getActiveRunsAsync = () => {
|
|
2967
|
+
return host.simulation.getActiveRunsAsync();
|
|
2968
|
+
};
|
|
2969
|
+
venusApi.simulation.collectRecipeAsync = (runId) => {
|
|
2970
|
+
return host.simulation.collectRecipeAsync(runId);
|
|
2971
|
+
};
|
|
2972
|
+
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, roomId, options) => {
|
|
2973
|
+
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, {
|
|
2974
|
+
roomId,
|
|
2975
|
+
...options
|
|
2976
|
+
});
|
|
2977
|
+
};
|
|
2978
|
+
venusApi.simulation.triggerRecipeChainAsync = (recipeId, context, roomId) => {
|
|
2979
|
+
return host.simulation.triggerRecipeChainAsync(recipeId, {
|
|
2980
|
+
context,
|
|
2981
|
+
roomId
|
|
2982
|
+
});
|
|
2983
|
+
};
|
|
2984
|
+
venusApi.simulation.getAvailableRecipesAsync = async (roomId, includeActorRecipes) => {
|
|
2985
|
+
const result = await host.simulation.getAvailableRecipesAsync({
|
|
2986
|
+
roomId,
|
|
2987
|
+
includeActorRecipes
|
|
2988
|
+
});
|
|
2989
|
+
return result.recipes;
|
|
2990
|
+
};
|
|
2991
|
+
venusApi.simulation.getRecipeRequirementsAsync = (recipeId, entity, amount) => {
|
|
2992
|
+
return host.simulation.getRecipeRequirementsAsync({
|
|
2993
|
+
recipeId,
|
|
2994
|
+
entity,
|
|
2995
|
+
batchAmount: amount
|
|
2996
|
+
});
|
|
2997
|
+
};
|
|
2998
|
+
venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
|
|
2999
|
+
return host.simulation.getBatchRecipeRequirementsAsync(recipes);
|
|
3000
|
+
};
|
|
3001
|
+
venusApi.simulation.resolveFieldValueAsync = (entityId, fieldPath, entity) => {
|
|
3002
|
+
return host.simulation.resolveFieldValueAsync(entityId, fieldPath, entity);
|
|
3003
|
+
};
|
|
3004
|
+
venusApi.simulation.getEntityMetadataAsync = (entityId) => {
|
|
3005
|
+
return host.simulation.getEntityMetadataAsync(entityId);
|
|
3006
|
+
};
|
|
3007
|
+
venusApi.simulation.getSlotAssignmentsAsync = (containerId) => {
|
|
3008
|
+
return host.simulation.getSlotAssignmentsAsync(containerId);
|
|
3009
|
+
};
|
|
3010
|
+
venusApi.simulation.getSlotContainersAsync = () => {
|
|
3011
|
+
return host.simulation.getSlotContainersAsync();
|
|
3012
|
+
};
|
|
3013
|
+
venusApi.simulation.assignItemToSlotAsync = (containerId, slotId, itemId) => {
|
|
3014
|
+
return host.simulation.assignItemToSlotAsync(containerId, slotId, itemId);
|
|
3015
|
+
};
|
|
3016
|
+
venusApi.simulation.removeItemFromSlotAsync = (containerId, slotId) => {
|
|
3017
|
+
return host.simulation.removeItemFromSlotAsync(containerId, slotId);
|
|
3018
|
+
};
|
|
3019
|
+
venusApi.simulation.getAvailableItemsAsync = (containerId, slotId) => {
|
|
3020
|
+
return host.simulation.getAvailableItemsAsync(containerId, slotId);
|
|
3021
|
+
};
|
|
3022
|
+
venusApi.simulation.calculatePowerPreviewAsync = (containerId, slotId, candidateItemId) => {
|
|
3023
|
+
return host.simulation.calculatePowerPreviewAsync(
|
|
3024
|
+
containerId,
|
|
3025
|
+
slotId,
|
|
3026
|
+
candidateItemId
|
|
3027
|
+
);
|
|
3028
|
+
};
|
|
3029
|
+
venusApi.simulation.executeBatchOperationsAsync = (operations, validateOnly) => {
|
|
3030
|
+
return host.simulation.executeBatchOperationsAsync(operations, validateOnly);
|
|
3031
|
+
};
|
|
3032
|
+
venusApi.simulation.validateSlotAssignmentAsync = (containerId, slotId, itemId) => {
|
|
3033
|
+
return host.simulation.validateSlotAssignmentAsync(
|
|
3034
|
+
containerId,
|
|
3035
|
+
slotId,
|
|
3036
|
+
itemId
|
|
3037
|
+
);
|
|
3038
|
+
};
|
|
3039
|
+
venusApi.simulation.sumContributions = (contributions) => {
|
|
3040
|
+
return host.simulation.sumContributions(contributions);
|
|
3041
|
+
};
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
// src/time/utils.ts
|
|
3045
|
+
function isPacificDaylightTime(date) {
|
|
3046
|
+
const year = date.getFullYear();
|
|
3047
|
+
const marchStart = new Date(year, 2, 8);
|
|
3048
|
+
const daysUntilSundayInMarch = (7 - marchStart.getDay()) % 7;
|
|
3049
|
+
const dstStart = new Date(year, 2, 8 + daysUntilSundayInMarch);
|
|
3050
|
+
dstStart.setHours(2, 0, 0, 0);
|
|
3051
|
+
const novemberStart = new Date(year, 10, 1);
|
|
3052
|
+
const daysUntilSundayInNov = (7 - novemberStart.getDay()) % 7;
|
|
3053
|
+
const dstEnd = new Date(year, 10, 1 + daysUntilSundayInNov);
|
|
3054
|
+
dstEnd.setHours(2, 0, 0, 0);
|
|
3055
|
+
return date >= dstStart && date < dstEnd;
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
// src/time/HostTimeApi.ts
|
|
3059
|
+
var HostTimeApi = class {
|
|
3060
|
+
constructor(rpcClient) {
|
|
3061
|
+
__publicField(this, "rpcClient");
|
|
3062
|
+
this.rpcClient = rpcClient;
|
|
3063
|
+
}
|
|
3064
|
+
async requestTimeAsync() {
|
|
3065
|
+
const response = await this.rpcClient.call(
|
|
3066
|
+
"H5_REQUEST_SERVER_TIME" /* REQUEST_SERVER_TIME */,
|
|
3067
|
+
{}
|
|
3068
|
+
);
|
|
3069
|
+
return response;
|
|
3070
|
+
}
|
|
3071
|
+
formatTime(timestamp, options) {
|
|
3072
|
+
let locale = "en-US";
|
|
3073
|
+
const windowVenus = window.venus;
|
|
3074
|
+
if (windowVenus._config.locale) {
|
|
3075
|
+
locale = windowVenus._config.locale;
|
|
3076
|
+
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3077
|
+
locale = windowVenus._config.environment.browserInfo.language;
|
|
3078
|
+
}
|
|
3079
|
+
const date = new Date(timestamp);
|
|
3080
|
+
const dateTimeOptions = {
|
|
3081
|
+
dateStyle: options.dateStyle || "medium",
|
|
3082
|
+
timeStyle: options.timeStyle || "medium",
|
|
3083
|
+
hour12: options.hour12 !== void 0 ? options.hour12 : true,
|
|
3084
|
+
...options
|
|
3085
|
+
};
|
|
3086
|
+
return date.toLocaleString(locale, dateTimeOptions);
|
|
3087
|
+
}
|
|
3088
|
+
formatNumber(value, options) {
|
|
3089
|
+
try {
|
|
3090
|
+
let locale = "en-US";
|
|
3091
|
+
const windowVenus = window.venus;
|
|
3092
|
+
if (windowVenus._config.locale) {
|
|
3093
|
+
locale = windowVenus._config.locale;
|
|
3094
|
+
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3095
|
+
locale = windowVenus._config.environment.browserInfo.language;
|
|
3096
|
+
}
|
|
3097
|
+
const numberOptions = {
|
|
3098
|
+
style: options?.style || "decimal",
|
|
3099
|
+
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
3100
|
+
maximumFractionDigits: options?.maximumFractionDigits || 2,
|
|
3101
|
+
...options
|
|
3102
|
+
};
|
|
3103
|
+
return value.toLocaleString(locale, numberOptions);
|
|
3104
|
+
} catch (error) {
|
|
3105
|
+
console.error("[Venus] Error formatting number:", error);
|
|
3106
|
+
return String(value);
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
async getFutureTimeAsync(options) {
|
|
3110
|
+
const timeInfo = await this.requestTimeAsync();
|
|
3111
|
+
const serverTime = new Date(timeInfo.serverTime);
|
|
3112
|
+
const result = new Date(serverTime);
|
|
3113
|
+
if (options?.days) {
|
|
3114
|
+
result.setDate(result.getDate() + options.days);
|
|
3115
|
+
}
|
|
3116
|
+
if (options?.hours) {
|
|
3117
|
+
result.setHours(result.getHours() + options.hours);
|
|
3118
|
+
}
|
|
3119
|
+
if (options?.minutes) {
|
|
3120
|
+
result.setMinutes(result.getMinutes() + options.minutes);
|
|
3121
|
+
}
|
|
3122
|
+
if (options?.timeOfDay) {
|
|
3123
|
+
const { hour = 0, minute = 0, second = 0 } = options.timeOfDay;
|
|
3124
|
+
timeInfo.timezoneOffset || (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
3125
|
+
const localHour = hour;
|
|
3126
|
+
result.setHours(localHour, minute, second, 0);
|
|
3127
|
+
}
|
|
3128
|
+
if (options?.timezone) {
|
|
3129
|
+
switch (options.timezone.toUpperCase()) {
|
|
3130
|
+
case "PT":
|
|
3131
|
+
case "PST":
|
|
3132
|
+
case "PDT": {
|
|
3133
|
+
const isPDT = isPacificDaylightTime(result);
|
|
3134
|
+
const ptOffset = isPDT ? -7 : -8;
|
|
3135
|
+
result.setUTCHours(0, 0, 0, 0);
|
|
3136
|
+
const { hour = 0, minute = 0, second = 0 } = options.timeOfDay || {};
|
|
3137
|
+
const utcHour = (hour - ptOffset) % 24;
|
|
3138
|
+
result.setUTCHours(utcHour, minute, second, 0);
|
|
3139
|
+
break;
|
|
3140
|
+
}
|
|
3141
|
+
// Add other timezone cases as needed
|
|
3142
|
+
default:
|
|
3143
|
+
console.warn(
|
|
3144
|
+
"[Venus] Timezone " + options.timezone + " not supported, using local time"
|
|
3145
|
+
);
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
return result.getTime();
|
|
3149
|
+
}
|
|
3150
|
+
};
|
|
3151
|
+
|
|
3152
|
+
// src/time/MockTimeApi.ts
|
|
3153
|
+
var MockTimeApi = class {
|
|
3154
|
+
constructor(venusApi) {
|
|
3155
|
+
__publicField(this, "venusApi");
|
|
3156
|
+
this.venusApi = venusApi;
|
|
3157
|
+
}
|
|
3158
|
+
formatNumber(value, options) {
|
|
3159
|
+
const locale = this.getLocale();
|
|
3160
|
+
const numberOptions = {
|
|
3161
|
+
style: options?.style || "decimal",
|
|
3162
|
+
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
3163
|
+
maximumFractionDigits: options?.maximumFractionDigits || 2,
|
|
3164
|
+
...options
|
|
3165
|
+
};
|
|
3166
|
+
console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
|
|
3167
|
+
return value.toLocaleString(locale, numberOptions);
|
|
3168
|
+
}
|
|
3169
|
+
formatTime(timestamp, options) {
|
|
3170
|
+
const locale = this.getLocale();
|
|
3171
|
+
const date = new Date(timestamp);
|
|
3172
|
+
const dateTimeOptions = {
|
|
3173
|
+
dateStyle: options.dateStyle || "medium",
|
|
3174
|
+
timeStyle: options.timeStyle || "medium",
|
|
3175
|
+
hour12: options.hour12 !== void 0 ? options.hour12 : true,
|
|
3176
|
+
...options
|
|
3177
|
+
};
|
|
3178
|
+
console.log(
|
|
3179
|
+
`[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
|
|
3180
|
+
);
|
|
3181
|
+
return date.toLocaleString(locale, dateTimeOptions);
|
|
3182
|
+
}
|
|
3183
|
+
async getFutureTimeAsync(options) {
|
|
3184
|
+
console.log("[Venus Mock] Getting future time with options:", options);
|
|
3185
|
+
const timeInfo = await this.requestTimeAsync();
|
|
3186
|
+
const serverTime = new Date(timeInfo.serverTime);
|
|
3187
|
+
const result = new Date(serverTime);
|
|
3188
|
+
if (options?.days) {
|
|
3189
|
+
result.setDate(result.getDate() + options.days);
|
|
3190
|
+
}
|
|
3191
|
+
if (options?.hours) {
|
|
3192
|
+
result.setHours(result.getHours() + options.hours);
|
|
3193
|
+
}
|
|
3194
|
+
if (options?.minutes) {
|
|
3195
|
+
result.setMinutes(result.getMinutes() + options.minutes);
|
|
3196
|
+
}
|
|
3197
|
+
if (options?.timeOfDay) {
|
|
3198
|
+
const { hour = 0, minute = 0, second = 0 } = options.timeOfDay;
|
|
3199
|
+
timeInfo.timezoneOffset || (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
3200
|
+
const localHour = hour;
|
|
3201
|
+
result.setHours(localHour, minute, second, 0);
|
|
3202
|
+
}
|
|
3203
|
+
if (options?.timezone) {
|
|
3204
|
+
switch (options?.timezone.toUpperCase()) {
|
|
3205
|
+
case "PT":
|
|
3206
|
+
case "PST":
|
|
3207
|
+
case "PDT": {
|
|
3208
|
+
const isPDT = isPacificDaylightTime(result);
|
|
3209
|
+
const ptOffset = isPDT ? -7 : -8;
|
|
3210
|
+
result.getUTCDate();
|
|
3211
|
+
result.getUTCMonth();
|
|
3212
|
+
result.getUTCFullYear();
|
|
3213
|
+
result.setUTCHours(0, 0, 0, 0);
|
|
3214
|
+
const { hour = 0, minute = 0, second = 0 } = options.timeOfDay || {};
|
|
3215
|
+
const utcHour = (hour - ptOffset) % 24;
|
|
3216
|
+
result.setUTCHours(utcHour, minute, second, 0);
|
|
3217
|
+
break;
|
|
3218
|
+
}
|
|
3219
|
+
// Add other timezone cases as needed
|
|
3220
|
+
default:
|
|
3221
|
+
console.warn(
|
|
3222
|
+
`[Venus Mock] Timezone ${options.timezone} not supported, using local time`
|
|
3223
|
+
);
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
return result.getTime();
|
|
3227
|
+
}
|
|
3228
|
+
async requestTimeAsync() {
|
|
3229
|
+
console.log("[Venus Mock] Requesting time");
|
|
3230
|
+
await createMockDelay(MOCK_DELAYS.short);
|
|
3231
|
+
const venusApi = this.venusApi;
|
|
3232
|
+
const mockOffset = venusApi._mock.serverTimeOffset || 2500;
|
|
3233
|
+
const mockServerTime = Date.now() + mockOffset;
|
|
3234
|
+
const timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
3235
|
+
const localTime = mockServerTime - timezoneOffset * 6e4;
|
|
3236
|
+
const timeInfo = {
|
|
3237
|
+
serverTime: mockServerTime,
|
|
3238
|
+
localTime,
|
|
3239
|
+
timezoneOffset,
|
|
3240
|
+
formattedTime: new Date(localTime).toISOString(),
|
|
3241
|
+
locale: venusApi._mock.user?.locale || "en-US"
|
|
3242
|
+
};
|
|
3243
|
+
console.log("[Venus Mock] Time response:", {
|
|
3244
|
+
serverTime: new Date(timeInfo.serverTime).toISOString(),
|
|
3245
|
+
localTime: new Date(timeInfo.localTime).toISOString(),
|
|
3246
|
+
timezoneOffset: timeInfo.timezoneOffset
|
|
3247
|
+
});
|
|
3248
|
+
return timeInfo;
|
|
3249
|
+
}
|
|
3250
|
+
getLocale() {
|
|
3251
|
+
const venusApi = this.venusApi;
|
|
3252
|
+
let locale = "en-US";
|
|
3253
|
+
if (venusApi._mock.user && venusApi._mock.user.locale) {
|
|
3254
|
+
locale = venusApi._mock.user.locale;
|
|
3255
|
+
} else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
|
|
3256
|
+
locale = venusApi._mock.environment.browserInfo.language;
|
|
3257
|
+
}
|
|
3258
|
+
return locale;
|
|
3259
|
+
}
|
|
3260
|
+
};
|
|
3261
|
+
|
|
3262
|
+
// src/time/index.ts
|
|
3263
|
+
function initializeTime(venusApi, host) {
|
|
3264
|
+
venusApi.requestTimeAsync = () => {
|
|
3265
|
+
return host.time.requestTimeAsync();
|
|
3266
|
+
};
|
|
3267
|
+
venusApi.getFutureTimeAsync = (options) => {
|
|
3268
|
+
return host.time.getFutureTimeAsync(options);
|
|
3269
|
+
};
|
|
3270
|
+
venusApi.formatTime = (timestamp, options) => {
|
|
3271
|
+
return host.time.formatTime(timestamp, options);
|
|
3272
|
+
};
|
|
3273
|
+
venusApi.formatNumber = (value, options) => {
|
|
3274
|
+
return host.time.formatNumber(value, options);
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
// src/version.ts
|
|
3279
|
+
var SDK_VERSION = "2.4.1";
|
|
3280
|
+
|
|
3281
|
+
// src/shared-assets/consts.ts
|
|
3282
|
+
var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
|
|
3283
|
+
var CharacterAssetsCdnPath = "burger-time/Character.stow";
|
|
3284
|
+
|
|
3285
|
+
// src/shared-assets/RpcSharedAssetsApi.ts
|
|
3286
|
+
var RpcSharedAssetsApi = class {
|
|
3287
|
+
constructor(rpcClient, venusApi) {
|
|
3288
|
+
__publicField(this, "venusApi");
|
|
3289
|
+
__publicField(this, "rpcClient");
|
|
3290
|
+
this.rpcClient = rpcClient;
|
|
3291
|
+
this.venusApi = venusApi;
|
|
3292
|
+
}
|
|
3293
|
+
async loadBurgerTimeAssetsBundle() {
|
|
3294
|
+
try {
|
|
3295
|
+
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3296
|
+
assetKey: "burgerTimeCoreBundle"
|
|
3297
|
+
});
|
|
3298
|
+
return base64ToArrayBuffer(response.base64Data);
|
|
3299
|
+
} catch (err) {
|
|
3300
|
+
try {
|
|
3301
|
+
const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
|
|
3302
|
+
return await blob.arrayBuffer();
|
|
3303
|
+
} catch (e) {
|
|
3304
|
+
throw new Error("Failed to load burgerTimeAssetsBundle");
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
async loadCharactersBundle() {
|
|
3309
|
+
try {
|
|
3310
|
+
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3311
|
+
assetKey: "characters"
|
|
3312
|
+
});
|
|
3313
|
+
return base64ToArrayBuffer(response.base64Data);
|
|
3314
|
+
} catch (err) {
|
|
3315
|
+
try {
|
|
3316
|
+
const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
|
|
3317
|
+
return await blob.arrayBuffer();
|
|
3318
|
+
} catch (e) {
|
|
3319
|
+
throw new Error("Failed to load charactersBundle");
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
function base64ToArrayBuffer(base64) {
|
|
3325
|
+
const binaryString = atob(base64);
|
|
3326
|
+
const len = binaryString.length;
|
|
3327
|
+
const bytes = new Uint8Array(len);
|
|
3328
|
+
for (let i = 0; i < len; i++) {
|
|
3329
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3330
|
+
}
|
|
3331
|
+
return bytes.buffer;
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
// src/shared-assets/MockSharedAssetsApi.ts
|
|
3335
|
+
var MockSharedAssetsApi = class {
|
|
3336
|
+
constructor(venusApi) {
|
|
3337
|
+
__publicField(this, "venusApi");
|
|
3338
|
+
this.venusApi = venusApi;
|
|
3339
|
+
}
|
|
3340
|
+
async loadBurgerTimeAssetsBundle() {
|
|
3341
|
+
const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
|
|
3342
|
+
return await blob.arrayBuffer();
|
|
3343
|
+
}
|
|
3344
|
+
async loadCharactersBundle() {
|
|
3345
|
+
const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
|
|
3346
|
+
return await blob.arrayBuffer();
|
|
3347
|
+
}
|
|
3348
|
+
};
|
|
3349
|
+
|
|
3350
|
+
export { HapticFeedbackStyle, HostCdnApi, HostProfileApi, HostTimeApi, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockProfileApi, MockSharedAssetsApi, MockSimulationApi, MockStorageApi, MockTimeApi, RpcAdsApi, RpcAiApi, RpcAnalyticsApi, RpcAvatarApi, RpcClient, RpcFeaturesApi, RpcHapticsApi, RpcIapApi, RpcLifecycleApi, RpcLoggingApi, RpcNavigationApi, RpcPopupsApi, RpcSharedAssetsApi, RpcSimulationApi, RpcStorageApi, SDK_VERSION, VenusMessageId, createMockStorageApi, initializeAds, initializeAi, initializeAnalytics, initializeAvatar3d, initializeCdn, initializeFeaturesApi, initializeHaptics, initializeIap, initializeLifecycleApi, initializeLocalNotifications, initializeLoggingApi, initializePopups, initializeProfile, initializeSimulation, initializeStackNavigation, initializeStorage, initializeTime, isPacificDaylightTime };
|
|
3351
|
+
//# sourceMappingURL=chunk-KQZIPQLJ.mjs.map
|
|
3352
|
+
//# sourceMappingURL=chunk-KQZIPQLJ.mjs.map
|