@series-inc/venus-sdk 3.0.4 → 3.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +324 -123
  2. package/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-meVfUcZy.d.mts} +37 -25
  3. package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-meVfUcZy.d.ts} +37 -25
  4. package/dist/chunk-2PDL7CQK.mjs +26 -0
  5. package/dist/chunk-2PDL7CQK.mjs.map +1 -0
  6. package/dist/{chunk-PXWCNWJ6.mjs → chunk-EMVTVSGL.mjs} +421 -109
  7. package/dist/chunk-EMVTVSGL.mjs.map +1 -0
  8. package/dist/chunk-IZLOB7DV.mjs +343 -0
  9. package/dist/chunk-IZLOB7DV.mjs.map +1 -0
  10. package/dist/{chunk-W7IPHM67.mjs → chunk-QABXMFND.mjs} +3 -26
  11. package/dist/chunk-QABXMFND.mjs.map +1 -0
  12. package/dist/core-5JLON75E.mjs +4 -0
  13. package/dist/{core-R3FHW62G.mjs.map → core-5JLON75E.mjs.map} +1 -1
  14. package/dist/index.cjs +768 -105
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.mts +140 -25
  17. package/dist/index.d.ts +140 -25
  18. package/dist/index.mjs +5 -3
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/venus-api/index.cjs +452 -101
  21. package/dist/venus-api/index.cjs.map +1 -1
  22. package/dist/venus-api/index.d.mts +2 -2
  23. package/dist/venus-api/index.d.ts +2 -2
  24. package/dist/venus-api/index.mjs +46 -3
  25. package/dist/venus-api/index.mjs.map +1 -1
  26. package/dist/vite/index.cjs +534 -0
  27. package/dist/vite/index.cjs.map +1 -0
  28. package/dist/vite/index.mjs +527 -0
  29. package/dist/vite/index.mjs.map +1 -0
  30. package/dist/webview/index.cjs +346 -0
  31. package/dist/webview/index.cjs.map +1 -0
  32. package/dist/webview/index.d.mts +17 -0
  33. package/dist/webview/index.d.ts +17 -0
  34. package/dist/webview/index.mjs +4 -0
  35. package/dist/webview/index.mjs.map +1 -0
  36. package/package.json +19 -1
  37. package/dist/chunk-PXWCNWJ6.mjs.map +0 -1
  38. package/dist/chunk-W7IPHM67.mjs.map +0 -1
  39. package/dist/core-R3FHW62G.mjs +0 -3
package/dist/index.cjs CHANGED
@@ -329,11 +329,11 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
329
329
  VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
330
330
  VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
331
331
  VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
332
- VenusMessageId2["H5_LEADERBOARD_START_RUN"] = "H5_LEADERBOARD_START_RUN";
332
+ VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
333
333
  VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
334
- VenusMessageId2["H5_LEADERBOARD_GET"] = "H5_LEADERBOARD_GET";
335
- VenusMessageId2["H5_LEADERBOARD_GET_HIGHLIGHT"] = "H5_LEADERBOARD_GET_HIGHLIGHT";
336
- VenusMessageId2["H5_LEADERBOARD_GET_PLAYER_STATS"] = "H5_LEADERBOARD_GET_PLAYER_STATS";
334
+ VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
335
+ VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
336
+ VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
337
337
  VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
338
338
  VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
339
339
  VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
@@ -3364,9 +3364,11 @@ function isPacificDaylightTime(date) {
3364
3364
 
3365
3365
  // src/time/HostTimeApi.ts
3366
3366
  var HostTimeApi = class {
3367
- constructor(rpcClient) {
3367
+ constructor(rpcClient, venusApi) {
3368
3368
  __publicField(this, "rpcClient");
3369
+ __publicField(this, "venusApi");
3369
3370
  this.rpcClient = rpcClient;
3371
+ this.venusApi = venusApi;
3370
3372
  }
3371
3373
  async requestTimeAsync() {
3372
3374
  const response = await this.rpcClient.call(
@@ -3376,13 +3378,7 @@ var HostTimeApi = class {
3376
3378
  return response;
3377
3379
  }
3378
3380
  formatTime(timestamp, options) {
3379
- let locale = "en-US";
3380
- const windowVenus = window.venus;
3381
- if (windowVenus._config.locale) {
3382
- locale = windowVenus._config.locale;
3383
- } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3384
- locale = windowVenus._config.environment.browserInfo.language;
3385
- }
3381
+ const locale = this.venusApi.getLocale();
3386
3382
  const date = new Date(timestamp);
3387
3383
  const dateTimeOptions = {
3388
3384
  dateStyle: options.dateStyle || "medium",
@@ -3394,13 +3390,7 @@ var HostTimeApi = class {
3394
3390
  }
3395
3391
  formatNumber(value, options) {
3396
3392
  try {
3397
- let locale = "en-US";
3398
- const windowVenus = window.venus;
3399
- if (windowVenus._config.locale) {
3400
- locale = windowVenus._config.locale;
3401
- } else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
3402
- locale = windowVenus._config.environment.browserInfo.language;
3403
- }
3393
+ const locale = this.venusApi.getLocale();
3404
3394
  const numberOptions = {
3405
3395
  style: options?.style || "decimal",
3406
3396
  minimumFractionDigits: options?.minimumFractionDigits || 0,
@@ -3463,7 +3453,7 @@ var MockTimeApi = class {
3463
3453
  this.venusApi = venusApi;
3464
3454
  }
3465
3455
  formatNumber(value, options) {
3466
- const locale = this.getLocale();
3456
+ const locale = this.venusApi.getLocale();
3467
3457
  const numberOptions = {
3468
3458
  style: options?.style || "decimal",
3469
3459
  minimumFractionDigits: options?.minimumFractionDigits || 0,
@@ -3474,7 +3464,7 @@ var MockTimeApi = class {
3474
3464
  return value.toLocaleString(locale, numberOptions);
3475
3465
  }
3476
3466
  formatTime(timestamp, options) {
3477
- const locale = this.getLocale();
3467
+ const locale = this.venusApi.getLocale();
3478
3468
  const date = new Date(timestamp);
3479
3469
  const dateTimeOptions = {
3480
3470
  dateStyle: options.dateStyle || "medium",
@@ -3554,16 +3544,6 @@ var MockTimeApi = class {
3554
3544
  });
3555
3545
  return timeInfo;
3556
3546
  }
3557
- getLocale() {
3558
- const venusApi = this.venusApi;
3559
- let locale = "en-US";
3560
- if (venusApi._mock.user && venusApi._mock.user.locale) {
3561
- locale = venusApi._mock.user.locale;
3562
- } else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
3563
- locale = venusApi._mock.environment.browserInfo.language;
3564
- }
3565
- return locale;
3566
- }
3567
3547
  };
3568
3548
 
3569
3549
  // src/time/index.ts
@@ -3583,12 +3563,181 @@ function initializeTime(venusApi, host) {
3583
3563
  }
3584
3564
 
3585
3565
  // src/version.ts
3586
- var SDK_VERSION = "3.0.4";
3566
+ var SDK_VERSION = "3.1.0-beta.0";
3587
3567
 
3588
3568
  // src/shared-assets/consts.ts
3589
3569
  var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
3590
3570
  var CharacterAssetsCdnPath = "burger-time/Character.stow";
3591
3571
 
3572
+ // src/shared-assets/embeddedLibrariesManifest.ts
3573
+ var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
3574
+ var EMBEDDED_LIBRARIES = [
3575
+ {
3576
+ libraryKey: "phaser@3.90.0",
3577
+ assetKey: "library:phaser@3.90.0",
3578
+ packageName: "phaser",
3579
+ version: "3.90.0",
3580
+ globalVar: "Phaser",
3581
+ cdnPath: "phaser/3.90.0/phaser.min.js",
3582
+ moduleSpecifiers: [{ match: "exact", value: "phaser" }],
3583
+ loadStage: 0,
3584
+ enabled: true
3585
+ },
3586
+ {
3587
+ libraryKey: "react@18.3.1",
3588
+ assetKey: "library:react@18.3.1",
3589
+ packageName: "react",
3590
+ version: "18.3.1",
3591
+ globalVar: "React",
3592
+ cdnPath: "react/18.3.1/react.production.min.js",
3593
+ moduleSpecifiers: [
3594
+ { match: "exact", value: "react", behavior: "namespace" },
3595
+ { match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
3596
+ {
3597
+ match: "exact",
3598
+ value: "react/jsx-dev-runtime",
3599
+ behavior: "react-jsx-dev-runtime"
3600
+ }
3601
+ ],
3602
+ loadStage: 0,
3603
+ // Must load before ReactDOM
3604
+ enabled: true
3605
+ },
3606
+ {
3607
+ libraryKey: "react-dom@18.3.1",
3608
+ assetKey: "library:react-dom@18.3.1",
3609
+ packageName: "react-dom",
3610
+ version: "18.3.1",
3611
+ globalVar: "ReactDOM",
3612
+ cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
3613
+ moduleSpecifiers: [
3614
+ { match: "exact", value: "react-dom", behavior: "namespace" },
3615
+ { match: "exact", value: "react-dom/client", behavior: "namespace" }
3616
+ ],
3617
+ loadStage: 1,
3618
+ // Depends on React (stage 0)
3619
+ enabled: true
3620
+ },
3621
+ {
3622
+ libraryKey: "three@0.170.0",
3623
+ assetKey: "library:three@0.170.0",
3624
+ packageName: "three",
3625
+ version: "0.170.0",
3626
+ globalVar: "THREE",
3627
+ cdnPath: "three/r170/three.min.js",
3628
+ moduleSpecifiers: [
3629
+ { match: "exact", value: "three", behavior: "namespace" },
3630
+ { match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
3631
+ ],
3632
+ loadStage: 0,
3633
+ enabled: true
3634
+ },
3635
+ {
3636
+ libraryKey: "matter-js@0.19.0",
3637
+ assetKey: "library:matter-js@0.19.0",
3638
+ packageName: "matter-js",
3639
+ version: "0.19.0",
3640
+ globalVar: "Matter",
3641
+ cdnPath: "matter-js/0.19.0/matter.min.js",
3642
+ moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
3643
+ loadStage: 0,
3644
+ enabled: true
3645
+ },
3646
+ {
3647
+ libraryKey: "inkjs@2.2.0",
3648
+ assetKey: "library:inkjs@2.2.0",
3649
+ packageName: "inkjs",
3650
+ version: "2.2.0",
3651
+ globalVar: "inkjs",
3652
+ cdnPath: "inkjs/2.2.0/ink.min.js",
3653
+ moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
3654
+ loadStage: 0,
3655
+ enabled: true
3656
+ },
3657
+ {
3658
+ libraryKey: "zustand@5.0.3",
3659
+ assetKey: "library:zustand@5.0.3",
3660
+ packageName: "zustand",
3661
+ version: "5.0.3",
3662
+ globalVar: "zustand",
3663
+ cdnPath: "zustand/5.0.3/zustand.min.js",
3664
+ moduleSpecifiers: [
3665
+ { match: "exact", value: "zustand" },
3666
+ { match: "exact", value: "zustand/middleware" }
3667
+ ],
3668
+ loadStage: 0,
3669
+ enabled: true
3670
+ },
3671
+ {
3672
+ libraryKey: "ammo.js@2024.11",
3673
+ assetKey: "library:ammo.js@2024.11",
3674
+ packageName: "ammo.js",
3675
+ version: "2024.11",
3676
+ globalVar: "Ammo",
3677
+ cdnPath: "ammo/2024.11/ammo.js",
3678
+ moduleSpecifiers: [
3679
+ { match: "exact", value: "ammo.js" },
3680
+ { match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
3681
+ ],
3682
+ loadStage: 0,
3683
+ enabled: false
3684
+ // Not ready yet - WASM loading needs additional work
3685
+ }
3686
+ ];
3687
+ var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
3688
+ (acc, lib) => {
3689
+ acc[lib.libraryKey] = lib;
3690
+ return acc;
3691
+ },
3692
+ {}
3693
+ );
3694
+ var MODULE_TO_LIBRARY_SPECIFIERS = EMBEDDED_LIBRARIES.filter(
3695
+ (lib) => lib.enabled
3696
+ ).flatMap(
3697
+ (lib) => lib.moduleSpecifiers.map((specifier) => ({
3698
+ ...specifier,
3699
+ libraryKey: lib.libraryKey
3700
+ }))
3701
+ );
3702
+ function getLibraryDefinition(libraryKey) {
3703
+ const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
3704
+ if (!definition) {
3705
+ const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
3706
+ throw new Error(
3707
+ `Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
3708
+ );
3709
+ }
3710
+ return definition;
3711
+ }
3712
+
3713
+ // src/shared-assets/base64Utils.ts
3714
+ function base64ToArrayBuffer(base64) {
3715
+ const binaryString = atob(base64);
3716
+ const len = binaryString.length;
3717
+ const bytes = new Uint8Array(len);
3718
+ for (let i = 0; i < len; i++) {
3719
+ bytes[i] = binaryString.charCodeAt(i);
3720
+ }
3721
+ return bytes.buffer;
3722
+ }
3723
+ function base64ToUtf8(base64) {
3724
+ if (typeof TextDecoder !== "undefined") {
3725
+ const decoder = new TextDecoder("utf-8");
3726
+ const buffer = base64ToArrayBuffer(base64);
3727
+ return decoder.decode(new Uint8Array(buffer));
3728
+ }
3729
+ if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
3730
+ const BufferCtor = globalThis.Buffer;
3731
+ return BufferCtor.from(base64, "base64").toString("utf-8");
3732
+ }
3733
+ const binaryString = atob(base64);
3734
+ let result = "";
3735
+ for (let i = 0; i < binaryString.length; i++) {
3736
+ result += String.fromCharCode(binaryString.charCodeAt(i));
3737
+ }
3738
+ return decodeURIComponent(escape(result));
3739
+ }
3740
+
3592
3741
  // src/shared-assets/RpcSharedAssetsApi.ts
3593
3742
  var RpcSharedAssetsApi = class {
3594
3743
  constructor(rpcClient, venusApi) {
@@ -3627,16 +3776,33 @@ var RpcSharedAssetsApi = class {
3627
3776
  }
3628
3777
  }
3629
3778
  }
3630
- };
3631
- function base64ToArrayBuffer(base64) {
3632
- const binaryString = atob(base64);
3633
- const len = binaryString.length;
3634
- const bytes = new Uint8Array(len);
3635
- for (let i = 0; i < len; i++) {
3636
- bytes[i] = binaryString.charCodeAt(i);
3779
+ async loadLibraryCode(libraryKey) {
3780
+ const definition = getLibraryDefinition(libraryKey);
3781
+ try {
3782
+ const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3783
+ assetKey: definition.assetKey
3784
+ });
3785
+ return base64ToUtf8(response.base64Data);
3786
+ } catch (err) {
3787
+ console.error(
3788
+ `[Venus Libraries] Failed to load ${libraryKey} from host via RPC:`,
3789
+ err
3790
+ );
3791
+ console.warn(
3792
+ `[Venus Libraries] Falling back to CDN for ${libraryKey}. This may indicate an asset packaging issue.`
3793
+ );
3794
+ try {
3795
+ const cdnUrl = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3796
+ const response = await this.venusApi.cdn.fetchFromCdn(cdnUrl);
3797
+ return await response.text();
3798
+ } catch (cdnError) {
3799
+ throw new Error(
3800
+ `Failed to load embedded library ${libraryKey}: RPC failed, CDN fallback failed: ${cdnError.message}`
3801
+ );
3802
+ }
3803
+ }
3637
3804
  }
3638
- return bytes.buffer;
3639
- }
3805
+ };
3640
3806
 
3641
3807
  // src/shared-assets/MockSharedAssetsApi.ts
3642
3808
  var MockSharedAssetsApi = class {
@@ -3652,49 +3818,114 @@ var MockSharedAssetsApi = class {
3652
3818
  const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
3653
3819
  return await blob.arrayBuffer();
3654
3820
  }
3821
+ async loadLibraryCode(libraryKey) {
3822
+ const definition = getLibraryDefinition(libraryKey);
3823
+ const url = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3824
+ const response = await this.venusApi.cdn.fetchFromCdn(url);
3825
+ return await response.text();
3826
+ }
3655
3827
  };
3656
3828
 
3829
+ // src/leaderboard/utils.ts
3830
+ var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
3831
+ var HASH_ALGORITHM_NODE = "sha256";
3832
+ async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
3833
+ const payload = `score:${score}|duration:${duration}|token:${token}`;
3834
+ const fullPayload = `${payload}|nonce:${sealingNonce}`;
3835
+ const encoder = new TextEncoder();
3836
+ const keyData = encoder.encode(sealingSecret);
3837
+ const messageData = encoder.encode(fullPayload);
3838
+ const cryptoKey = await crypto.subtle.importKey(
3839
+ "raw",
3840
+ keyData,
3841
+ { name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
3842
+ false,
3843
+ ["sign"]
3844
+ );
3845
+ const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
3846
+ return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
3847
+ }
3848
+
3657
3849
  // src/leaderboard/RpcLeaderboardApi.ts
3658
3850
  var RpcLeaderboardApi = class {
3659
3851
  constructor(rpcClient) {
3660
3852
  __publicField(this, "rpcClient");
3853
+ /** Cache of score tokens for automatic hash computation */
3854
+ __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3661
3855
  this.rpcClient = rpcClient;
3662
3856
  }
3663
- startRun(mode) {
3664
- return this.rpcClient.call(
3665
- "H5_LEADERBOARD_START_RUN" /* H5_LEADERBOARD_START_RUN */,
3857
+ /**
3858
+ * Create a score token for submitting a score.
3859
+ * Token is cached for automatic hash computation if score sealing is enabled.
3860
+ *
3861
+ * @param mode - Optional game mode
3862
+ * @returns Score token with sealing data if enabled
3863
+ */
3864
+ async createScoreToken(mode) {
3865
+ const token = await this.rpcClient.call(
3866
+ "H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
3666
3867
  mode ? { mode } : {}
3667
3868
  );
3869
+ this.tokenCache.set(token.token, token);
3870
+ return token;
3668
3871
  }
3669
- submitScore(sessionId, score, durationSec, options) {
3872
+ /**
3873
+ * Submit a score to the leaderboard.
3874
+ * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
3875
+ *
3876
+ * @param params - Score submission parameters
3877
+ * @returns Submission result with acceptance status and rank
3878
+ * @throws Error if token not found in cache
3879
+ */
3880
+ async submitScore(params) {
3881
+ let hash;
3882
+ if (params.token) {
3883
+ const cachedToken = this.tokenCache.get(params.token);
3884
+ if (!cachedToken) {
3885
+ throw new Error(
3886
+ "Invalid token: not found in cache. Did you call createScoreToken() first?"
3887
+ );
3888
+ }
3889
+ if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
3890
+ hash = await computeScoreHash(
3891
+ params.score,
3892
+ params.duration,
3893
+ params.token,
3894
+ cachedToken.sealingNonce,
3895
+ cachedToken.sealingSecret
3896
+ );
3897
+ }
3898
+ this.tokenCache.delete(params.token);
3899
+ }
3670
3900
  return this.rpcClient.call(
3671
3901
  "H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
3672
3902
  {
3673
- sessionId,
3674
- score,
3675
- durationSec,
3676
- mode: options?.mode,
3677
- telemetry: options?.telemetry,
3678
- metadata: options?.metadata,
3679
- hash: options?.hash
3903
+ token: params.token,
3904
+ score: params.score,
3905
+ duration: params.duration,
3906
+ mode: params.mode,
3907
+ telemetry: params.telemetry,
3908
+ metadata: params.metadata,
3909
+ hash
3910
+ // undefined if no sealing, computed if sealing enabled
3680
3911
  }
3681
3912
  );
3682
3913
  }
3683
- getLeaderboard(options) {
3914
+ getPagedScores(options) {
3684
3915
  return this.rpcClient.call(
3685
- "H5_LEADERBOARD_GET" /* H5_LEADERBOARD_GET */,
3916
+ "H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
3686
3917
  options ?? {}
3687
3918
  );
3688
3919
  }
3689
- getPlayerStats(options) {
3920
+ getMyRank(options) {
3690
3921
  return this.rpcClient.call(
3691
- "H5_LEADERBOARD_GET_PLAYER_STATS" /* H5_LEADERBOARD_GET_PLAYER_STATS */,
3922
+ "H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
3692
3923
  options ?? {}
3693
3924
  );
3694
3925
  }
3695
- getLeaderboardHighlight(options) {
3926
+ getPodiumScores(options) {
3696
3927
  return this.rpcClient.call(
3697
- "H5_LEADERBOARD_GET_HIGHLIGHT" /* H5_LEADERBOARD_GET_HIGHLIGHT */,
3928
+ "H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
3698
3929
  options ?? {}
3699
3930
  );
3700
3931
  }
@@ -3703,17 +3934,31 @@ var RpcLeaderboardApi = class {
3703
3934
  // src/leaderboard/MockLeaderboardApi.ts
3704
3935
  var MockLeaderboardApi = class {
3705
3936
  constructor(options) {
3706
- __publicField(this, "sessions", /* @__PURE__ */ new Map());
3937
+ __publicField(this, "tokens", /* @__PURE__ */ new Map());
3938
+ /** Cache of score tokens for automatic hash computation */
3939
+ __publicField(this, "tokenCache", /* @__PURE__ */ new Map());
3707
3940
  __publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
3708
- __publicField(this, "sessionCounter", 0);
3709
- __publicField(this, "requiresHash", false);
3710
- if (options?.requiresHash) {
3711
- this.requiresHash = true;
3941
+ __publicField(this, "tokenCounter", 0);
3942
+ __publicField(this, "enableScoreSealing", false);
3943
+ __publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
3944
+ if (options?.enableScoreSealing) {
3945
+ this.enableScoreSealing = true;
3946
+ }
3947
+ if (options?.scoreSealingSecret) {
3948
+ this.scoreSealingSecret = options.scoreSealingSecret;
3712
3949
  }
3713
3950
  }
3951
+ /**
3952
+ * Configure mock leaderboard settings
3953
+ *
3954
+ * @param options - Configuration options
3955
+ */
3714
3956
  configure(options) {
3715
- if (typeof options.requiresHash === "boolean") {
3716
- this.requiresHash = options.requiresHash;
3957
+ if (typeof options.enableScoreSealing === "boolean") {
3958
+ this.enableScoreSealing = options.enableScoreSealing;
3959
+ }
3960
+ if (options.scoreSealingSecret) {
3961
+ this.scoreSealingSecret = options.scoreSealingSecret;
3717
3962
  }
3718
3963
  }
3719
3964
  generateNonce() {
@@ -3730,83 +3975,149 @@ var MockLeaderboardApi = class {
3730
3975
  }
3731
3976
  return this.entriesByMode.get(key);
3732
3977
  }
3733
- async startRun(mode) {
3734
- const sessionId = `mock_session_${++this.sessionCounter}`;
3978
+ /**
3979
+ * Create a mock score token for testing.
3980
+ * Token is cached for automatic hash computation if score sealing is enabled.
3981
+ *
3982
+ * @param mode - Optional game mode
3983
+ * @returns Score token with sealing data if enabled
3984
+ */
3985
+ async createScoreToken(mode) {
3986
+ const token = `mock_token_${++this.tokenCounter}`;
3735
3987
  const startTime = Date.now();
3736
3988
  const expiresAt = startTime + 36e5;
3737
3989
  const resolvedMode = mode || "default";
3738
- const hashNonce = this.requiresHash ? this.generateNonce() : null;
3739
- this.sessions.set(sessionId, {
3740
- id: sessionId,
3990
+ const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
3991
+ const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
3992
+ this.tokens.set(token, {
3993
+ id: token,
3741
3994
  expiresAt,
3742
3995
  mode: resolvedMode,
3743
- hashNonce,
3996
+ sealingNonce,
3744
3997
  used: false
3745
3998
  });
3746
- return {
3747
- sessionId,
3999
+ const result = {
4000
+ token,
3748
4001
  startTime,
3749
4002
  expiresAt,
3750
- hashNonce,
4003
+ sealingNonce,
4004
+ sealingSecret,
3751
4005
  mode: resolvedMode
3752
4006
  };
4007
+ this.tokenCache.set(token, result);
4008
+ return result;
3753
4009
  }
3754
- async submitScore(sessionId, score, durationSec, options) {
3755
- const session = this.sessions.get(sessionId);
3756
- if (!session) {
3757
- throw new Error("Invalid leaderboard session");
4010
+ /**
4011
+ * Submit a mock score to the leaderboard.
4012
+ * Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
4013
+ *
4014
+ * @param params - Score submission parameters
4015
+ * @returns Submission result with acceptance status and rank
4016
+ * @throws Error if token not found in cache or validation fails
4017
+ */
4018
+ async submitScore(params) {
4019
+ let hash;
4020
+ if (params.token) {
4021
+ const cachedToken = this.tokenCache.get(params.token);
4022
+ if (!cachedToken) {
4023
+ throw new Error(
4024
+ "Invalid token: not found in cache. Did you call createScoreToken() first?"
4025
+ );
4026
+ }
4027
+ if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
4028
+ hash = await computeScoreHash(
4029
+ params.score,
4030
+ params.duration,
4031
+ params.token,
4032
+ cachedToken.sealingNonce,
4033
+ cachedToken.sealingSecret
4034
+ );
4035
+ }
4036
+ }
4037
+ if (!params.token) {
4038
+ const mode = params.mode || "default";
4039
+ const submittedAt2 = Date.now();
4040
+ const entry2 = {
4041
+ profileId: `mock_profile`,
4042
+ username: "Mock Player",
4043
+ avatarUrl: null,
4044
+ score: params.score,
4045
+ duration: params.duration,
4046
+ submittedAt: submittedAt2,
4047
+ token: "simple-mode",
4048
+ rank: null,
4049
+ zScore: null,
4050
+ isAnomaly: false,
4051
+ trustScore: 50,
4052
+ metadata: params.metadata ?? null,
4053
+ isSeed: false
4054
+ };
4055
+ const modeEntries2 = this.getEntriesForMode(mode);
4056
+ modeEntries2.push(entry2);
4057
+ modeEntries2.sort((a, b) => {
4058
+ if (b.score !== a.score) return b.score - a.score;
4059
+ return a.submittedAt - b.submittedAt;
4060
+ });
4061
+ modeEntries2.forEach((e, index) => {
4062
+ modeEntries2[index] = { ...e, rank: index + 1 };
4063
+ });
4064
+ const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
4065
+ return {
4066
+ accepted: true,
4067
+ rank: inserted2?.rank ?? null
4068
+ };
4069
+ }
4070
+ const scoreToken = this.tokens.get(params.token);
4071
+ if (!scoreToken) {
4072
+ throw new Error("Invalid score token");
3758
4073
  }
3759
- if (session.expiresAt < Date.now()) {
3760
- throw new Error("Invalid or expired leaderboard session");
4074
+ if (scoreToken.expiresAt < Date.now()) {
4075
+ throw new Error("Invalid or expired score token");
3761
4076
  }
3762
- if (session.used) {
3763
- throw new Error("Leaderboard session already used");
4077
+ if (scoreToken.used) {
4078
+ throw new Error("Score token already used");
3764
4079
  }
3765
- if (options?.mode && options.mode !== session.mode) {
3766
- throw new Error("Submission mode does not match session mode");
4080
+ if (params.mode && params.mode !== scoreToken.mode) {
4081
+ throw new Error("Submission mode does not match token mode");
3767
4082
  }
3768
- if (session.hashNonce && !options?.hash) {
3769
- throw new Error("Score hash is required for sealed leaderboard submissions");
4083
+ if (scoreToken.sealingNonce && !hash) {
4084
+ throw new Error("Score hash required when score sealing is enabled");
3770
4085
  }
3771
4086
  const submittedAt = Date.now();
3772
4087
  const entry = {
3773
4088
  profileId: `mock_profile`,
3774
4089
  username: "Mock Player",
3775
4090
  avatarUrl: null,
3776
- score,
3777
- durationSec,
4091
+ score: params.score,
4092
+ duration: params.duration,
3778
4093
  submittedAt,
3779
- sessionId,
4094
+ token: params.token,
3780
4095
  rank: null,
3781
4096
  zScore: null,
3782
4097
  isAnomaly: false,
3783
4098
  trustScore: 50,
3784
- metadata: options?.metadata ?? null,
4099
+ metadata: params.metadata ?? null,
3785
4100
  isSeed: false
3786
4101
  };
3787
- const modeEntries = this.getEntriesForMode(session.mode);
4102
+ const modeEntries = this.getEntriesForMode(scoreToken.mode);
3788
4103
  modeEntries.push(entry);
3789
4104
  modeEntries.sort((a, b) => {
3790
- if (b.score !== a.score) {
3791
- return b.score - a.score;
3792
- }
4105
+ if (b.score !== a.score) return b.score - a.score;
3793
4106
  return a.submittedAt - b.submittedAt;
3794
4107
  });
3795
4108
  modeEntries.forEach((e, index) => {
3796
- modeEntries[index] = {
3797
- ...e,
3798
- rank: index + 1
3799
- };
4109
+ modeEntries[index] = { ...e, rank: index + 1 };
3800
4110
  });
3801
- session.used = true;
3802
- session.hashNonce = null;
3803
- const inserted = modeEntries.find((e) => e.sessionId === sessionId && e.submittedAt === submittedAt);
4111
+ scoreToken.used = true;
4112
+ scoreToken.sealingNonce = null;
4113
+ this.tokenCache.delete(params.token);
4114
+ const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
3804
4115
  return {
3805
4116
  accepted: true,
3806
4117
  rank: inserted?.rank ?? null
3807
4118
  };
3808
4119
  }
3809
- async getLeaderboard(options) {
4120
+ async getPagedScores(options) {
3810
4121
  const limit = options?.limit ?? 10;
3811
4122
  const mode = options?.mode ?? "default";
3812
4123
  const modeEntries = [...this.getEntriesForMode(mode)];
@@ -3822,7 +4133,7 @@ var MockLeaderboardApi = class {
3822
4133
  periodInstance: options?.period ?? "alltime"
3823
4134
  };
3824
4135
  }
3825
- async getPlayerStats(_options) {
4136
+ async getMyRank(_options) {
3826
4137
  const mode = _options?.mode ?? "default";
3827
4138
  const modeEntries = this.getEntriesForMode(mode);
3828
4139
  const playerEntry = modeEntries[0] ?? null;
@@ -3835,7 +4146,7 @@ var MockLeaderboardApi = class {
3835
4146
  periodInstance: _options?.period ?? "alltime"
3836
4147
  };
3837
4148
  }
3838
- async getLeaderboardHighlight(options) {
4149
+ async getPodiumScores(options) {
3839
4150
  const mode = options?.mode ?? "default";
3840
4151
  const modeEntries = [...this.getEntriesForMode(mode)];
3841
4152
  const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
@@ -5222,7 +5533,7 @@ var RemoteHost = class {
5222
5533
  this.popups = new RpcPopupsApi(rpcClient);
5223
5534
  this.profile = new HostProfileApi();
5224
5535
  this.cdn = new HostCdnApi(getCdnBaseUrl());
5225
- this.time = new HostTimeApi(rpcClient);
5536
+ this.time = new HostTimeApi(rpcClient, venusApi);
5226
5537
  this.post = new RpcPostApi(rpcClient);
5227
5538
  this.ai = new RpcAiApi(rpcClient);
5228
5539
  this.haptics = new RpcHapticsApi(rpcClient);
@@ -5313,10 +5624,356 @@ function initializeSocial(venusApi, host) {
5313
5624
  };
5314
5625
  }
5315
5626
 
5627
+ // src/webview/webviewLibraryShimSource.ts
5628
+ var WEBVIEW_LIBRARY_SHIM_SOURCE = `
5629
+ (function () {
5630
+ if (typeof window === 'undefined') {
5631
+ return;
5632
+ }
5633
+
5634
+ if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {
5635
+ return;
5636
+ }
5637
+
5638
+ var RESPONSE_TYPE = 'H5_RESPONSE';
5639
+ var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET';
5640
+ var REQUEST_TIMEOUT_MS = 12000;
5641
+ var pendingRequests = new Map();
5642
+
5643
+ function ensureConfig() {
5644
+ if (!window.__venusLibrariesConfig) {
5645
+ window.__venusLibrariesConfig = {
5646
+ enabled: false,
5647
+ required: [],
5648
+ manifest: {},
5649
+ cdnBase: ''
5650
+ };
5651
+ }
5652
+ if (!window.__venusLibrariesConfig.manifest) {
5653
+ window.__venusLibrariesConfig.manifest = {};
5654
+ }
5655
+ if (!Array.isArray(window.__venusLibrariesConfig.required)) {
5656
+ window.__venusLibrariesConfig.required = [];
5657
+ }
5658
+ return window.__venusLibrariesConfig;
5659
+ }
5660
+
5661
+ function ensureExportsRegistry() {
5662
+ if (!window.__venusLibraryExports) {
5663
+ window.__venusLibraryExports = {};
5664
+ }
5665
+ return window.__venusLibraryExports;
5666
+ }
5667
+
5668
+ function hasHostBridge() {
5669
+ return !!(window.ReactNativeWebView && typeof window.ReactNativeWebView.postMessage === 'function');
5670
+ }
5671
+
5672
+ function registerResponseListeners() {
5673
+ if (window.__venusLibraryShim && window.__venusLibraryShim.__listenerRegistered) {
5674
+ return;
5675
+ }
5676
+
5677
+ function handleMessage(event) {
5678
+ var payload = parsePayload(event && event.data);
5679
+ if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {
5680
+ return;
5681
+ }
5682
+ var requestId = payload.data.requestId;
5683
+ if (!requestId || !pendingRequests.has(requestId)) {
5684
+ return;
5685
+ }
5686
+ var pending = pendingRequests.get(requestId);
5687
+ pendingRequests.delete(requestId);
5688
+ clearTimeout(pending.timeout);
5689
+
5690
+ if (payload.data.success === false) {
5691
+ pending.reject(new Error(payload.data.error || 'Embedded library load failed'));
5692
+ return;
5693
+ }
5694
+
5695
+ var value = payload.data.value || payload.data;
5696
+ if (!value || !value.base64Data) {
5697
+ pending.reject(new Error('Embedded library response was missing base64Data'));
5698
+ return;
5699
+ }
5700
+
5701
+ pending.resolve(value.base64Data);
5702
+ }
5703
+
5704
+ if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
5705
+ document.addEventListener('message', handleMessage, false);
5706
+ }
5707
+ if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
5708
+ window.addEventListener('message', handleMessage, false);
5709
+ }
5710
+
5711
+ if (!window.__venusLibraryShim) {
5712
+ window.__venusLibraryShim = {};
5713
+ }
5714
+ window.__venusLibraryShim.__listenerRegistered = true;
5715
+ }
5716
+
5717
+ function parsePayload(raw) {
5718
+ if (!raw || typeof raw !== 'string') {
5719
+ return null;
5720
+ }
5721
+ try {
5722
+ return JSON.parse(raw);
5723
+ } catch (error) {
5724
+ return null;
5725
+ }
5726
+ }
5727
+
5728
+ function createRequestId(libraryKey) {
5729
+ var sanitized = '';
5730
+ for (var i = 0; i < libraryKey.length; i++) {
5731
+ var c = libraryKey.charAt(i);
5732
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '-' || c === '_') {
5733
+ sanitized += c;
5734
+ } else {
5735
+ sanitized += '_';
5736
+ }
5737
+ }
5738
+ return 'embedded-lib-' + sanitized + '-' + Date.now() + '-' + Math.random().toString(36).slice(2);
5739
+ }
5740
+
5741
+ function postHostRequest(assetKey, requestId) {
5742
+ if (!hasHostBridge()) {
5743
+ throw new Error('Host bridge is unavailable');
5744
+ }
5745
+ var bridge = window.ReactNativeWebView;
5746
+ var message = {
5747
+ type: REQUEST_TYPE,
5748
+ direction: 'H5_TO_APP',
5749
+ data: {
5750
+ requestId: requestId,
5751
+ assetKey: assetKey
5752
+ },
5753
+ instanceId: (window._venusInitState && window._venusInitState.poolId) || 'unknown',
5754
+ timestamp: Date.now()
5755
+ };
5756
+ bridge.postMessage(JSON.stringify(message));
5757
+ }
5758
+
5759
+ function loadLibraryViaHost(assetKey, libraryKey) {
5760
+ return new Promise(function (resolve, reject) {
5761
+ var requestId = createRequestId(libraryKey);
5762
+ var timeout = setTimeout(function () {
5763
+ pendingRequests.delete(requestId);
5764
+ reject(new Error('Timed out loading embedded library: ' + libraryKey));
5765
+ }, REQUEST_TIMEOUT_MS);
5766
+
5767
+ pendingRequests.set(requestId, { resolve: resolve, reject: reject, timeout: timeout });
5768
+
5769
+ try {
5770
+ postHostRequest(assetKey, requestId);
5771
+ } catch (error) {
5772
+ pendingRequests.delete(requestId);
5773
+ clearTimeout(timeout);
5774
+ reject(error);
5775
+ }
5776
+ });
5777
+ }
5778
+
5779
+ function buildCdnUrl(config, entry) {
5780
+ var base = config.cdnBase || '';
5781
+ if (!base.endsWith('/')) {
5782
+ base += '/';
5783
+ }
5784
+ var path = entry.cdnPath;
5785
+ if (path.charAt(0) === '/') {
5786
+ path = path.substring(1);
5787
+ }
5788
+ return base + path;
5789
+ }
5790
+
5791
+ async function loadLibraryViaCdn(config, entry, libraryKey) {
5792
+ if (!config.cdnBase) {
5793
+ throw new Error('CDN base URL is not configured');
5794
+ }
5795
+ var url = buildCdnUrl(config, entry);
5796
+ var response = await fetch(url, { credentials: 'omit' });
5797
+ if (!response.ok) {
5798
+ throw new Error('Failed to fetch embedded library from CDN: ' + libraryKey);
5799
+ }
5800
+ return await response.text();
5801
+ }
5802
+
5803
+ function decodeBase64ToUtf8(base64) {
5804
+ if (typeof base64 !== 'string') {
5805
+ throw new Error('Invalid base64 payload');
5806
+ }
5807
+
5808
+ if (typeof atob === 'function') {
5809
+ var binary = atob(base64);
5810
+ if (typeof TextDecoder !== 'undefined') {
5811
+ var len = binary.length;
5812
+ var bytes = new Uint8Array(len);
5813
+ for (var i = 0; i < len; i++) {
5814
+ bytes[i] = binary.charCodeAt(i);
5815
+ }
5816
+ return new TextDecoder('utf-8').decode(bytes);
5817
+ }
5818
+ return decodeURIComponent(escape(binary));
5819
+ }
5820
+
5821
+ var bufferCtor = (typeof globalThis !== 'undefined' && globalThis.Buffer) || (typeof window !== 'undefined' && window.Buffer);
5822
+ if (bufferCtor) {
5823
+ return bufferCtor.from(base64, 'base64').toString('utf-8');
5824
+ }
5825
+
5826
+ throw new Error('No base64 decoder available');
5827
+ }
5828
+
5829
+ function evaluateLibrarySource(libraryKey, globalVar, source) {
5830
+ var registry = ensureExportsRegistry();
5831
+ if (!source) {
5832
+ throw new Error('Embedded library source was empty for ' + libraryKey);
5833
+ }
5834
+
5835
+ var previousValue = window[globalVar];
5836
+ try {
5837
+ var executor = new Function(source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js');
5838
+ executor.call(window);
5839
+ } catch (error) {
5840
+ throw new Error('Failed to evaluate embedded library ' + libraryKey + ': ' + (error && error.message ? error.message : error));
5841
+ }
5842
+
5843
+ var exported = window[globalVar] || previousValue;
5844
+ if (!exported) {
5845
+ throw new Error('Embedded library ' + libraryKey + ' did not register ' + globalVar);
5846
+ }
5847
+
5848
+ registry[libraryKey] = exported;
5849
+ return exported;
5850
+ }
5851
+
5852
+ async function ensureLibraryLoaded(config, libraryKey) {
5853
+ var registry = ensureExportsRegistry();
5854
+ if (registry[libraryKey]) {
5855
+ return registry[libraryKey];
5856
+ }
5857
+
5858
+ var entry = config.manifest && config.manifest[libraryKey];
5859
+ if (!entry) {
5860
+ throw new Error('No manifest entry for embedded library ' + libraryKey);
5861
+ }
5862
+
5863
+ var source = null;
5864
+ if (config.useHost !== false && hasHostBridge()) {
5865
+ try {
5866
+ var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey);
5867
+ source = decodeBase64ToUtf8(base64);
5868
+ } catch (error) {
5869
+ // Log the RPC error loudly before fallback
5870
+ console.error('[Venus Libraries] Failed to load ' + libraryKey + ' from host via RPC:', error);
5871
+ console.warn('[Venus Libraries] Falling back to CDN for ' + libraryKey + '. This may indicate an asset packaging issue.');
5872
+ }
5873
+ }
5874
+
5875
+ if (!source) {
5876
+ source = await loadLibraryViaCdn(config, entry, libraryKey);
5877
+ }
5878
+
5879
+ return evaluateLibrarySource(libraryKey, entry.globalVar, source);
5880
+ }
5881
+
5882
+ async function bootstrap() {
5883
+ try {
5884
+ registerResponseListeners();
5885
+ getBootstrapPromise();
5886
+
5887
+ var config = ensureConfig();
5888
+
5889
+ if (!config.enabled) {
5890
+ if (bootstrapResolve) bootstrapResolve();
5891
+ return;
5892
+ }
5893
+
5894
+ if (!Array.isArray(config.required) || config.required.length === 0) {
5895
+ if (bootstrapResolve) bootstrapResolve();
5896
+ return;
5897
+ }
5898
+
5899
+ // Group libraries by load stage for parallel loading within stages
5900
+ var librariesByStage = {};
5901
+ for (var i = 0; i < config.required.length; i++) {
5902
+ var libraryKey = config.required[i];
5903
+ var entry = config.manifest[libraryKey];
5904
+ var stage = entry.loadStage || 0;
5905
+ if (!librariesByStage[stage]) librariesByStage[stage] = [];
5906
+ librariesByStage[stage].push(libraryKey);
5907
+ }
5908
+
5909
+ // Load stages sequentially, libraries within each stage in parallel
5910
+ var stages = Object.keys(librariesByStage).sort(function(a, b) {
5911
+ return parseInt(a, 10) - parseInt(b, 10);
5912
+ });
5913
+
5914
+ for (var s = 0; s < stages.length; s++) {
5915
+ var stage = stages[s];
5916
+ var libs = librariesByStage[stage];
5917
+
5918
+ // Load all libraries in this stage in parallel
5919
+ var stagePromises = libs.map(function(libraryKey) {
5920
+ return ensureLibraryLoaded(config, libraryKey).catch(function(error) {
5921
+ console.error('[Venus Libraries] Failed to load library ' + libraryKey, error);
5922
+ throw error;
5923
+ });
5924
+ });
5925
+
5926
+ await Promise.all(stagePromises);
5927
+ }
5928
+
5929
+ if (bootstrapResolve) bootstrapResolve();
5930
+ } catch (error) {
5931
+ console.error('[Venus Libraries] Bootstrap error', error);
5932
+ if (bootstrapReject) bootstrapReject(error);
5933
+ throw error;
5934
+ }
5935
+ }
5936
+
5937
+ // Create a promise that resolves when bootstrap completes
5938
+ var bootstrapPromise = null;
5939
+ var bootstrapResolve = null;
5940
+ var bootstrapReject = null;
5941
+
5942
+ function getBootstrapPromise() {
5943
+ if (!bootstrapPromise) {
5944
+ bootstrapPromise = new Promise(function(resolve, reject) {
5945
+ bootstrapResolve = resolve;
5946
+ bootstrapReject = reject;
5947
+ });
5948
+ }
5949
+ return bootstrapPromise;
5950
+ }
5951
+
5952
+ window.__venusLibraryShim = {
5953
+ bootstrap: bootstrap,
5954
+ ready: getBootstrapPromise,
5955
+ getExports: function (libraryKey) {
5956
+ var registry = ensureExportsRegistry();
5957
+ return registry[libraryKey];
5958
+ },
5959
+ __initialized: true,
5960
+ };
5961
+ })();
5962
+ `;
5963
+ function getWebviewLibraryShimSource() {
5964
+ return WEBVIEW_LIBRARY_SHIM_SOURCE;
5965
+ }
5966
+
5967
+ exports.DEFAULT_SHARED_LIB_CDN_BASE = DEFAULT_SHARED_LIB_CDN_BASE;
5968
+ exports.EMBEDDED_LIBRARIES = EMBEDDED_LIBRARIES;
5969
+ exports.EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARY_BY_KEY;
5970
+ exports.HASH_ALGORITHM_NODE = HASH_ALGORITHM_NODE;
5971
+ exports.HASH_ALGORITHM_WEB_CRYPTO = HASH_ALGORITHM_WEB_CRYPTO;
5316
5972
  exports.HapticFeedbackStyle = HapticFeedbackStyle;
5317
5973
  exports.HostCdnApi = HostCdnApi;
5318
5974
  exports.HostProfileApi = HostProfileApi;
5319
5975
  exports.HostTimeApi = HostTimeApi;
5976
+ exports.MODULE_TO_LIBRARY_SPECIFIERS = MODULE_TO_LIBRARY_SPECIFIERS;
5320
5977
  exports.MockAdsApi = MockAdsApi;
5321
5978
  exports.MockAiApi = MockAiApi;
5322
5979
  exports.MockAnalyticsApi = MockAnalyticsApi;
@@ -5360,8 +6017,14 @@ exports.RpcSocialApi = RpcSocialApi;
5360
6017
  exports.RpcStorageApi = RpcStorageApi;
5361
6018
  exports.SDK_VERSION = SDK_VERSION;
5362
6019
  exports.VenusMessageId = VenusMessageId;
6020
+ exports.WEBVIEW_LIBRARY_SHIM_SOURCE = WEBVIEW_LIBRARY_SHIM_SOURCE;
6021
+ exports.base64ToArrayBuffer = base64ToArrayBuffer;
6022
+ exports.base64ToUtf8 = base64ToUtf8;
6023
+ exports.computeScoreHash = computeScoreHash;
5363
6024
  exports.createHost = createHost;
5364
6025
  exports.createMockStorageApi = createMockStorageApi;
6026
+ exports.getLibraryDefinition = getLibraryDefinition;
6027
+ exports.getWebviewLibraryShimSource = getWebviewLibraryShimSource;
5365
6028
  exports.initializeAds = initializeAds;
5366
6029
  exports.initializeAi = initializeAi;
5367
6030
  exports.initializeAnalytics = initializeAnalytics;