@series-inc/venus-sdk 3.2.0 → 3.2.1-beta.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/dist/index.cjs CHANGED
@@ -46,9 +46,6 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
46
46
  VenusMessageId2["IS_LOCAL_NOTIFICATIONS_ENABLED"] = "H5_IS_LOCAL_NOTIFICATIONS_ENABLED";
47
47
  VenusMessageId2["SET_LOCAL_NOTIFICATIONS_ENABLED"] = "H5_SET_LOCAL_NOTIFICATIONS_ENABLED";
48
48
  VenusMessageId2["TOAST"] = "H5_TOAST";
49
- VenusMessageId2["ALERT_DIALOG"] = "H5_ALERT_DIALOG";
50
- VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
51
- VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
52
49
  VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
53
50
  VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
54
51
  VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
@@ -964,7 +961,7 @@ var MockCdnApi = class {
964
961
  const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
965
962
  const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
966
963
  if (isLocalhost && !this.forceRemoteCdn) {
967
- return `/${cleanSubPath}`;
964
+ return `cdn/${cleanSubPath}`;
968
965
  }
969
966
  const pathParts = cleanSubPath.split("/");
970
967
  const encodedParts = pathParts.map((part, index) => {
@@ -1929,40 +1926,6 @@ var RpcPopupsApi = class {
1929
1926
  __publicField(this, "rpcClient");
1930
1927
  this.rpcClient = rpcClient;
1931
1928
  }
1932
- async showActionSheet(items, options) {
1933
- const result = await this.rpcClient.call(
1934
- "H5_ACTION_SHEET_SHOW" /* ACTION_SHEET_SHOW */,
1935
- {
1936
- title: options?.title || "",
1937
- message: options?.message || "",
1938
- options: items,
1939
- cancelButtonText: options?.cancelButtonText || "Cancel"
1940
- }
1941
- );
1942
- return result;
1943
- }
1944
- async showAlert(title, message, options) {
1945
- const buttonText = options?.buttonText || "OK";
1946
- await this.rpcClient.call("H5_ALERT_DIALOG" /* ALERT_DIALOG */, {
1947
- title,
1948
- message,
1949
- buttonText
1950
- });
1951
- }
1952
- async showConfirm(title, message, options) {
1953
- const confirmText = options?.confirmText || "OK";
1954
- const cancelText = options?.cancelText || "Cancel";
1955
- const result = await this.rpcClient.call(
1956
- "H5_CONFIRM_DIALOG" /* CONFIRM_DIALOG */,
1957
- {
1958
- title,
1959
- message,
1960
- confirmText,
1961
- cancelText
1962
- }
1963
- );
1964
- return result;
1965
- }
1966
1929
  async showToast(message, options) {
1967
1930
  const duration = options?.duration ?? 3e3;
1968
1931
  const variant = options?.variant ?? "info";
@@ -1986,21 +1949,6 @@ var MockPopupsApi = class {
1986
1949
  __publicField(this, "overlay");
1987
1950
  this.overlay = override;
1988
1951
  }
1989
- showActionSheet(items, options) {
1990
- console.log(
1991
- `[Venus Mock] Show Action sheet, items: ${JSON.stringify(items, null, 2)}, options: ${JSON.stringify(options, null, 2)}`
1992
- );
1993
- return this.overlay.showActionSheet(items, options);
1994
- }
1995
- async showAlert(title, message, options) {
1996
- window.alert(`${title}
1997
- ${message}`);
1998
- }
1999
- async showConfirm(title, message, options) {
2000
- const result = window.confirm(`${title || "Confirm"}
2001
- ${message}`);
2002
- return result;
2003
- }
2004
1952
  async showToast(message, options) {
2005
1953
  const variant = options?.variant ?? "info";
2006
1954
  const duration = options?.duration ?? 3e3;
@@ -2027,41 +1975,6 @@ ${message}`);
2027
1975
 
2028
1976
  // src/popups/index.ts
2029
1977
  function initializePopups(venusApi, host) {
2030
- venusApi.showToast = async (input) => {
2031
- if (typeof input === "string") {
2032
- return await host.popups.showToast(input);
2033
- } else {
2034
- return await host.popups.showToast(input.message, {
2035
- duration: input.duration,
2036
- action: input.action,
2037
- variant: "success"
2038
- });
2039
- }
2040
- };
2041
- venusApi.showAlert = async (input) => {
2042
- await host.popups.showAlert(input.title, input.message, {
2043
- buttonText: input.buttonText
2044
- });
2045
- };
2046
- venusApi.showConfirm = async (input) => {
2047
- const confirmed = await host.popups.showConfirm(
2048
- input.title,
2049
- input.message,
2050
- {
2051
- confirmText: input.confirmText,
2052
- cancelText: input.cancelText
2053
- }
2054
- );
2055
- return confirmed;
2056
- };
2057
- venusApi.showActionSheet = async (input) => {
2058
- return await host.popups.showActionSheet(input.options, {
2059
- title: input.title,
2060
- message: input.message,
2061
- cancelButtonText: input.cancelButtonText,
2062
- disableCancel: input.disableCancel
2063
- });
2064
- };
2065
1978
  venusApi.popups = host.popups;
2066
1979
  }
2067
1980
 
@@ -2647,21 +2560,23 @@ function initializeRoomsApi(venusApi, host) {
2647
2560
  }
2648
2561
 
2649
2562
  // src/storage/MockStorageApi.ts
2563
+ var STORAGE_PREFIXES = {
2564
+ globalStorage: "venus:global",
2565
+ deviceCache: "venus:deviceCache",
2566
+ appStorage: "venus:appStorage"
2567
+ };
2650
2568
  function createMockStorageApi(storageType, appUrl) {
2651
2569
  const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
2652
- let prefix;
2570
+ let prefix = STORAGE_PREFIXES[storageType];
2653
2571
  let syncDelay = 0;
2654
2572
  switch (storageType) {
2655
2573
  case "deviceCache":
2656
- prefix = "venus:app";
2657
2574
  syncDelay = 0;
2658
2575
  break;
2659
2576
  case "appStorage":
2660
- prefix = "venus:app";
2661
2577
  syncDelay = 100;
2662
2578
  break;
2663
2579
  case "globalStorage":
2664
- prefix = "venus:global";
2665
2580
  syncDelay = 100;
2666
2581
  break;
2667
2582
  default:
@@ -2674,29 +2589,38 @@ var MockStorageApi = class {
2674
2589
  constructor(prefix, syncDelay) {
2675
2590
  __publicField(this, "prefix");
2676
2591
  __publicField(this, "syncDelay");
2592
+ __publicField(this, "orderStorageKey");
2677
2593
  this.prefix = prefix;
2678
2594
  this.syncDelay = syncDelay;
2595
+ this.orderStorageKey = `${prefix}__order__`;
2679
2596
  }
2680
2597
  async clear() {
2598
+ const keysToRemove = [];
2681
2599
  const fullLength = localStorage.length;
2682
2600
  for (let i = 0; i < fullLength; i++) {
2683
2601
  const fullKey = localStorage.key(i);
2684
- if (fullKey && fullKey.startsWith(this.prefix)) {
2685
- localStorage.removeItem(fullKey);
2602
+ if (!fullKey || fullKey === this.orderStorageKey) {
2603
+ continue;
2604
+ }
2605
+ if (fullKey.startsWith(this.prefix)) {
2606
+ keysToRemove.push(fullKey);
2686
2607
  }
2687
2608
  }
2609
+ for (const key of keysToRemove) {
2610
+ localStorage.removeItem(key);
2611
+ }
2612
+ this.clearOrder();
2688
2613
  await this.simulateSyncDelay();
2689
2614
  }
2690
2615
  async getAllItems() {
2691
2616
  const items = new Array();
2692
- const fullLength = localStorage.length;
2693
- for (let i = 0; i < fullLength; i++) {
2694
- const fullKey = localStorage.key(i);
2695
- if (fullKey && fullKey.startsWith(this.prefix)) {
2696
- const item = localStorage.getItem(fullKey);
2697
- if (item) {
2698
- items.push(item);
2699
- }
2617
+ const orderedKeys = this.keys();
2618
+ for (const key of orderedKeys) {
2619
+ const value = localStorage.getItem(this.buildKey(key));
2620
+ if (value !== null) {
2621
+ items.push(value);
2622
+ } else {
2623
+ this.removeFromOrder(key);
2700
2624
  }
2701
2625
  }
2702
2626
  return items;
@@ -2721,11 +2645,13 @@ var MockStorageApi = class {
2721
2645
  const fullKey = this.buildKey(key);
2722
2646
  await this.simulateSyncDelay();
2723
2647
  localStorage.removeItem(fullKey);
2648
+ this.removeFromOrder(key);
2724
2649
  }
2725
2650
  async setItem(key, item) {
2726
2651
  const fullKey = this.buildKey(key);
2727
2652
  await this.simulateSyncDelay();
2728
2653
  localStorage.setItem(fullKey, item);
2654
+ this.upsertOrder(key);
2729
2655
  }
2730
2656
  async setMultipleItems(entries) {
2731
2657
  for (const entry of entries) {
@@ -2733,6 +2659,7 @@ var MockStorageApi = class {
2733
2659
  localStorage.setItem(fullKey, entry.value);
2734
2660
  }
2735
2661
  await this.simulateSyncDelay();
2662
+ this.bulkUpsertOrder(entries.map((entry) => entry.key));
2736
2663
  }
2737
2664
  async removeMultipleItems(keys) {
2738
2665
  for (const key of keys) {
@@ -2740,6 +2667,7 @@ var MockStorageApi = class {
2740
2667
  localStorage.removeItem(fullKey);
2741
2668
  }
2742
2669
  await this.simulateSyncDelay();
2670
+ this.bulkRemoveFromOrder(keys);
2743
2671
  }
2744
2672
  buildKey(key) {
2745
2673
  const prefix = this.prefix;
@@ -2750,17 +2678,8 @@ var MockStorageApi = class {
2750
2678
  return fullKey.substring(prefix.length);
2751
2679
  }
2752
2680
  keys() {
2753
- const keys = new Array();
2754
- let length = localStorage.length;
2755
- for (let i = 0; i < length; i++) {
2756
- const fullKey = localStorage.key(i);
2757
- if (fullKey && fullKey.startsWith(this.prefix)) {
2758
- length++;
2759
- const key = this.extractKey(fullKey);
2760
- keys.push(key);
2761
- }
2762
- }
2763
- return keys;
2681
+ const order = this.readOrder();
2682
+ return [...order];
2764
2683
  }
2765
2684
  async simulateSyncDelay() {
2766
2685
  const syncDelay = this.syncDelay;
@@ -2768,6 +2687,127 @@ var MockStorageApi = class {
2768
2687
  await new Promise((resolve) => setTimeout(resolve, syncDelay));
2769
2688
  }
2770
2689
  }
2690
+ readOrder() {
2691
+ const raw = localStorage.getItem(this.orderStorageKey);
2692
+ if (!raw) {
2693
+ return this.rebuildOrderFromStorage();
2694
+ }
2695
+ try {
2696
+ const parsed = JSON.parse(raw);
2697
+ if (Array.isArray(parsed)) {
2698
+ return this.normalizeOrder(parsed);
2699
+ }
2700
+ } catch {
2701
+ }
2702
+ return this.rebuildOrderFromStorage();
2703
+ }
2704
+ normalizeOrder(order) {
2705
+ const seen = /* @__PURE__ */ new Set();
2706
+ const normalized = [];
2707
+ let changed = false;
2708
+ for (const entry of order) {
2709
+ if (typeof entry !== "string") {
2710
+ changed = true;
2711
+ continue;
2712
+ }
2713
+ if (seen.has(entry)) {
2714
+ changed = true;
2715
+ continue;
2716
+ }
2717
+ const fullKey = this.buildKey(entry);
2718
+ if (localStorage.getItem(fullKey) === null) {
2719
+ changed = true;
2720
+ continue;
2721
+ }
2722
+ seen.add(entry);
2723
+ normalized.push(entry);
2724
+ }
2725
+ if (changed) {
2726
+ this.writeOrder(normalized);
2727
+ }
2728
+ return normalized;
2729
+ }
2730
+ rebuildOrderFromStorage() {
2731
+ const keys = [];
2732
+ const total = localStorage.length;
2733
+ for (let i = 0; i < total; i++) {
2734
+ const fullKey = localStorage.key(i);
2735
+ if (!fullKey) continue;
2736
+ if (fullKey === this.orderStorageKey) continue;
2737
+ if (fullKey.startsWith(this.prefix)) {
2738
+ keys.push(this.extractKey(fullKey));
2739
+ }
2740
+ }
2741
+ this.writeOrder(keys);
2742
+ return keys;
2743
+ }
2744
+ upsertOrder(key) {
2745
+ const order = this.readOrder();
2746
+ const index = order.indexOf(key);
2747
+ if (index !== -1) {
2748
+ order.splice(index, 1);
2749
+ }
2750
+ order.push(key);
2751
+ this.writeOrder(order);
2752
+ }
2753
+ bulkUpsertOrder(keys) {
2754
+ const dedupedKeys = this.dedupeKeys(keys);
2755
+ if (dedupedKeys.length === 0) {
2756
+ return;
2757
+ }
2758
+ const order = this.readOrder();
2759
+ const keysSet = new Set(dedupedKeys);
2760
+ const filtered = order.filter((entry) => !keysSet.has(entry));
2761
+ for (const key of dedupedKeys) {
2762
+ filtered.push(key);
2763
+ }
2764
+ this.writeOrder(filtered);
2765
+ }
2766
+ removeFromOrder(key) {
2767
+ const order = this.readOrder();
2768
+ const index = order.indexOf(key);
2769
+ if (index !== -1) {
2770
+ order.splice(index, 1);
2771
+ this.writeOrder(order);
2772
+ }
2773
+ }
2774
+ bulkRemoveFromOrder(keys) {
2775
+ const dedupedKeys = this.dedupeKeys(keys);
2776
+ if (dedupedKeys.length === 0) {
2777
+ return;
2778
+ }
2779
+ const order = this.readOrder();
2780
+ const keysSet = new Set(dedupedKeys);
2781
+ const filtered = order.filter((entry) => !keysSet.has(entry));
2782
+ if (filtered.length !== order.length) {
2783
+ this.writeOrder(filtered);
2784
+ }
2785
+ }
2786
+ writeOrder(order) {
2787
+ if (order.length === 0) {
2788
+ localStorage.removeItem(this.orderStorageKey);
2789
+ return;
2790
+ }
2791
+ localStorage.setItem(this.orderStorageKey, JSON.stringify(order));
2792
+ }
2793
+ clearOrder() {
2794
+ localStorage.removeItem(this.orderStorageKey);
2795
+ }
2796
+ dedupeKeys(keys) {
2797
+ const result = [];
2798
+ const seen = /* @__PURE__ */ new Set();
2799
+ for (const key of keys) {
2800
+ if (typeof key !== "string") {
2801
+ continue;
2802
+ }
2803
+ if (seen.has(key)) {
2804
+ continue;
2805
+ }
2806
+ seen.add(key);
2807
+ result.push(key);
2808
+ }
2809
+ return result;
2810
+ }
2771
2811
  };
2772
2812
  function generateAppIdentifier(appUrl) {
2773
2813
  if (!appUrl) appUrl = "";
@@ -3438,7 +3478,72 @@ function initializeTime(venusApi, host) {
3438
3478
  }
3439
3479
 
3440
3480
  // src/version.ts
3441
- var SDK_VERSION = "3.2.0";
3481
+ var SDK_VERSION = "3.2.1-beta.1";
3482
+
3483
+ // src/shared-assets/base64Utils.ts
3484
+ function base64ToArrayBuffer(base64) {
3485
+ const binaryString = atob(base64);
3486
+ const len = binaryString.length;
3487
+ const bytes = new Uint8Array(len);
3488
+ for (let i = 0; i < len; i++) {
3489
+ bytes[i] = binaryString.charCodeAt(i);
3490
+ }
3491
+ return bytes.buffer;
3492
+ }
3493
+ function base64ToUtf8(base64) {
3494
+ if (typeof TextDecoder !== "undefined") {
3495
+ const decoder = new TextDecoder("utf-8");
3496
+ const buffer = base64ToArrayBuffer(base64);
3497
+ return decoder.decode(new Uint8Array(buffer));
3498
+ }
3499
+ if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
3500
+ const BufferCtor = globalThis.Buffer;
3501
+ return BufferCtor.from(base64, "base64").toString("utf-8");
3502
+ }
3503
+ const binaryString = atob(base64);
3504
+ let result = "";
3505
+ for (let i = 0; i < binaryString.length; i++) {
3506
+ result += String.fromCharCode(binaryString.charCodeAt(i));
3507
+ }
3508
+ return decodeURIComponent(escape(result));
3509
+ }
3510
+
3511
+ // src/shared-assets/RpcSharedAssetsApi.ts
3512
+ var RpcSharedAssetsApi = class {
3513
+ constructor(rpcClient, venusApi) {
3514
+ __publicField(this, "venusApi");
3515
+ __publicField(this, "rpcClient");
3516
+ this.rpcClient = rpcClient;
3517
+ this.venusApi = venusApi;
3518
+ }
3519
+ async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3520
+ try {
3521
+ const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3522
+ assetKey: bundleKey
3523
+ });
3524
+ return base64ToArrayBuffer(response.base64Data);
3525
+ } catch (err) {
3526
+ try {
3527
+ const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3528
+ return await blob.arrayBuffer();
3529
+ } catch (e) {
3530
+ throw new Error(`Failed to load ${bundleKey}`);
3531
+ }
3532
+ }
3533
+ }
3534
+ };
3535
+
3536
+ // src/shared-assets/MockSharedAssetsApi.ts
3537
+ var MockSharedAssetsApi = class {
3538
+ constructor(venusApi) {
3539
+ __publicField(this, "venusApi");
3540
+ this.venusApi = venusApi;
3541
+ }
3542
+ async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3543
+ const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3544
+ return await blob.arrayBuffer();
3545
+ }
3546
+ };
3442
3547
 
3443
3548
  // src/shared-assets/embeddedLibrariesManifest.ts
3444
3549
  var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
@@ -3581,103 +3686,6 @@ function getLibraryDefinition(libraryKey) {
3581
3686
  return definition;
3582
3687
  }
3583
3688
 
3584
- // src/shared-assets/base64Utils.ts
3585
- function base64ToArrayBuffer(base64) {
3586
- const binaryString = atob(base64);
3587
- const len = binaryString.length;
3588
- const bytes = new Uint8Array(len);
3589
- for (let i = 0; i < len; i++) {
3590
- bytes[i] = binaryString.charCodeAt(i);
3591
- }
3592
- return bytes.buffer;
3593
- }
3594
- function base64ToUtf8(base64) {
3595
- if (typeof TextDecoder !== "undefined") {
3596
- const decoder = new TextDecoder("utf-8");
3597
- const buffer = base64ToArrayBuffer(base64);
3598
- return decoder.decode(new Uint8Array(buffer));
3599
- }
3600
- if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
3601
- const BufferCtor = globalThis.Buffer;
3602
- return BufferCtor.from(base64, "base64").toString("utf-8");
3603
- }
3604
- const binaryString = atob(base64);
3605
- let result = "";
3606
- for (let i = 0; i < binaryString.length; i++) {
3607
- result += String.fromCharCode(binaryString.charCodeAt(i));
3608
- }
3609
- return decodeURIComponent(escape(result));
3610
- }
3611
-
3612
- // src/shared-assets/RpcSharedAssetsApi.ts
3613
- var RpcSharedAssetsApi = class {
3614
- constructor(rpcClient, venusApi) {
3615
- __publicField(this, "venusApi");
3616
- __publicField(this, "rpcClient");
3617
- this.rpcClient = rpcClient;
3618
- this.venusApi = venusApi;
3619
- }
3620
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3621
- try {
3622
- const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3623
- assetKey: bundleKey
3624
- });
3625
- return base64ToArrayBuffer(response.base64Data);
3626
- } catch (err) {
3627
- try {
3628
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3629
- return await blob.arrayBuffer();
3630
- } catch (e) {
3631
- throw new Error(`Failed to load ${bundleKey}`);
3632
- }
3633
- }
3634
- }
3635
- async loadLibraryCode(libraryKey) {
3636
- const definition = getLibraryDefinition(libraryKey);
3637
- try {
3638
- const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
3639
- assetKey: definition.assetKey
3640
- });
3641
- return base64ToUtf8(response.base64Data);
3642
- } catch (err) {
3643
- console.error(
3644
- `[Venus Libraries] Failed to load ${libraryKey} from host via RPC:`,
3645
- err
3646
- );
3647
- console.warn(
3648
- `[Venus Libraries] Falling back to CDN for ${libraryKey}. This may indicate an asset packaging issue.`
3649
- );
3650
- try {
3651
- const cdnUrl = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3652
- const response = await this.venusApi.cdn.fetchFromCdn(cdnUrl);
3653
- return await response.text();
3654
- } catch (cdnError) {
3655
- throw new Error(
3656
- `Failed to load embedded library ${libraryKey}: RPC failed, CDN fallback failed: ${cdnError.message}`
3657
- );
3658
- }
3659
- }
3660
- }
3661
- };
3662
-
3663
- // src/shared-assets/MockSharedAssetsApi.ts
3664
- var MockSharedAssetsApi = class {
3665
- constructor(venusApi) {
3666
- __publicField(this, "venusApi");
3667
- this.venusApi = venusApi;
3668
- }
3669
- async loadAssetsBundle(game, bundleKey, fileType = "stow") {
3670
- const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
3671
- return await blob.arrayBuffer();
3672
- }
3673
- async loadLibraryCode(libraryKey) {
3674
- const definition = getLibraryDefinition(libraryKey);
3675
- const url = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
3676
- const response = await this.venusApi.cdn.fetchFromCdn(url);
3677
- return await response.text();
3678
- }
3679
- };
3680
-
3681
3689
  // src/leaderboard/utils.ts
3682
3690
  var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
3683
3691
  var HASH_ALGORITHM_NODE = "sha256";
@@ -5160,7 +5168,7 @@ function initializeSocial(venusApi, host) {
5160
5168
  };
5161
5169
  }
5162
5170
 
5163
- // raw-loader:/Users/pchan/Development/series/venus/venus-sdk/packages/api/src/webview/webviewLibraryShim.js
5171
+ // raw-loader:E:\SeriesAI\venus\venus-sdk\packages\api\src\webview\webviewLibraryShim.js
5164
5172
  var webviewLibraryShim_default = "/**\r\n * Venus Embedded Libraries WebView Shim\r\n *\r\n * This code is injected into H5 game WebViews BEFORE the game's main script runs.\r\n * It bootstraps the embedded libraries system by:\r\n * 1. Reading window.__venusLibrariesConfig (set by the Vite plugin)\r\n * 2. Loading libraries via RPC (mobile) or CDN (web)\r\n * 3. Registering libraries in window.__venusLibraryExports\r\n * 4. Allowing the game's virtual modules to access them\r\n *\r\n * This shim is NOT imported by H5 games - it's injected by the Venus host via\r\n * injectedJavaScriptBeforeContentLoaded in H5AppPoolRenderer.\r\n */\r\n\r\n;(function () {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {\r\n return\r\n }\r\n\r\n var RESPONSE_TYPE = 'H5_RESPONSE'\r\n var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET'\r\n var REQUEST_TIMEOUT_MS = 12000\r\n var pendingRequests = new Map()\r\n\r\n function ensureConfig() {\r\n if (!window.__venusLibrariesConfig) {\r\n window.__venusLibrariesConfig = {\r\n enabled: false,\r\n required: [],\r\n manifest: {},\r\n cdnBase: '',\r\n }\r\n }\r\n if (!window.__venusLibrariesConfig.manifest) {\r\n window.__venusLibrariesConfig.manifest = {}\r\n }\r\n if (!Array.isArray(window.__venusLibrariesConfig.required)) {\r\n window.__venusLibrariesConfig.required = []\r\n }\r\n return window.__venusLibrariesConfig\r\n }\r\n\r\n function ensureExportsRegistry() {\r\n if (!window.__venusLibraryExports) {\r\n window.__venusLibraryExports = {}\r\n }\r\n return window.__venusLibraryExports\r\n }\r\n\r\n function hasHostBridge() {\r\n return !!(\r\n window.ReactNativeWebView &&\r\n typeof window.ReactNativeWebView.postMessage === 'function'\r\n )\r\n }\r\n\r\n function registerResponseListeners() {\r\n if (\r\n window.__venusLibraryShim &&\r\n window.__venusLibraryShim.__listenerRegistered\r\n ) {\r\n return\r\n }\r\n\r\n function handleMessage(event) {\r\n var payload = parsePayload(event && event.data)\r\n if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {\r\n return\r\n }\r\n var requestId = payload.data.requestId\r\n if (!requestId || !pendingRequests.has(requestId)) {\r\n return\r\n }\r\n var pending = pendingRequests.get(requestId)\r\n pendingRequests.delete(requestId)\r\n clearTimeout(pending.timeout)\r\n\r\n if (payload.data.success === false) {\r\n pending.reject(\r\n new Error(payload.data.error || 'Embedded library load failed'),\r\n )\r\n return\r\n }\r\n\r\n var value = payload.data.value || payload.data\r\n if (!value || !value.base64Data) {\r\n pending.reject(\r\n new Error('Embedded library response was missing base64Data'),\r\n )\r\n return\r\n }\r\n\r\n pending.resolve(value.base64Data)\r\n }\r\n\r\n if (\r\n typeof document !== 'undefined' &&\r\n typeof document.addEventListener === 'function'\r\n ) {\r\n document.addEventListener('message', handleMessage, false)\r\n }\r\n if (\r\n typeof window !== 'undefined' &&\r\n typeof window.addEventListener === 'function'\r\n ) {\r\n window.addEventListener('message', handleMessage, false)\r\n }\r\n\r\n if (!window.__venusLibraryShim) {\r\n window.__venusLibraryShim = {}\r\n }\r\n window.__venusLibraryShim.__listenerRegistered = true\r\n }\r\n\r\n function parsePayload(raw) {\r\n if (!raw || typeof raw !== 'string') {\r\n return null\r\n }\r\n try {\r\n return JSON.parse(raw)\r\n } catch (error) {\r\n return null\r\n }\r\n }\r\n\r\n function createRequestId(libraryKey) {\r\n var sanitized = ''\r\n for (var i = 0; i < libraryKey.length; i++) {\r\n var c = libraryKey.charAt(i)\r\n if (\r\n (c >= 'a' && c <= 'z') ||\r\n (c >= 'A' && c <= 'Z') ||\r\n (c >= '0' && c <= '9') ||\r\n c === '-' ||\r\n c === '_'\r\n ) {\r\n sanitized += c\r\n } else {\r\n sanitized += '_'\r\n }\r\n }\r\n return (\r\n 'embedded-lib-' +\r\n sanitized +\r\n '-' +\r\n Date.now() +\r\n '-' +\r\n Math.random().toString(36).slice(2)\r\n )\r\n }\r\n\r\n function postHostRequest(assetKey, requestId) {\r\n if (!hasHostBridge()) {\r\n throw new Error('Host bridge is unavailable')\r\n }\r\n var bridge = window.ReactNativeWebView\r\n var message = {\r\n type: REQUEST_TYPE,\r\n direction: 'H5_TO_APP',\r\n data: {\r\n requestId: requestId,\r\n assetKey: assetKey,\r\n },\r\n instanceId:\r\n (window._venusInitState && window._venusInitState.poolId) || 'unknown',\r\n timestamp: Date.now(),\r\n }\r\n bridge.postMessage(JSON.stringify(message))\r\n }\r\n\r\n function loadLibraryViaHost(assetKey, libraryKey) {\r\n return new Promise(function (resolve, reject) {\r\n var requestId = createRequestId(libraryKey)\r\n var timeout = setTimeout(function () {\r\n pendingRequests.delete(requestId)\r\n reject(new Error('Timed out loading embedded library: ' + libraryKey))\r\n }, REQUEST_TIMEOUT_MS)\r\n\r\n pendingRequests.set(requestId, {\r\n resolve: resolve,\r\n reject: reject,\r\n timeout: timeout,\r\n })\r\n\r\n try {\r\n postHostRequest(assetKey, requestId)\r\n } catch (error) {\r\n pendingRequests.delete(requestId)\r\n clearTimeout(timeout)\r\n reject(error)\r\n }\r\n })\r\n }\r\n\r\n function buildCdnUrl(config, entry) {\r\n var base = config.cdnBase || ''\r\n if (!base.endsWith('/')) {\r\n base += '/'\r\n }\r\n var path = entry.cdnPath\r\n if (path.charAt(0) === '/') {\r\n path = path.substring(1)\r\n }\r\n return base + path\r\n }\r\n\r\n async function loadLibraryViaCdn(config, entry, libraryKey) {\r\n if (!config.cdnBase) {\r\n throw new Error('CDN base URL is not configured')\r\n }\r\n var url = buildCdnUrl(config, entry)\r\n var response = await fetch(url, { credentials: 'omit' })\r\n if (!response.ok) {\r\n throw new Error(\r\n 'Failed to fetch embedded library from CDN: ' + libraryKey,\r\n )\r\n }\r\n return await response.text()\r\n }\r\n\r\n function decodeBase64ToUtf8(base64) {\r\n if (typeof base64 !== 'string') {\r\n throw new Error('Invalid base64 payload')\r\n }\r\n\r\n if (typeof atob === 'function') {\r\n var binary = atob(base64)\r\n if (typeof TextDecoder !== 'undefined') {\r\n var len = binary.length\r\n var bytes = new Uint8Array(len)\r\n for (var i = 0; i < len; i++) {\r\n bytes[i] = binary.charCodeAt(i)\r\n }\r\n return new TextDecoder('utf-8').decode(bytes)\r\n }\r\n return decodeURIComponent(escape(binary))\r\n }\r\n\r\n var bufferCtor =\r\n (typeof globalThis !== 'undefined' && globalThis.Buffer) ||\r\n (typeof window !== 'undefined' && window.Buffer)\r\n if (bufferCtor) {\r\n return bufferCtor.from(base64, 'base64').toString('utf-8')\r\n }\r\n\r\n throw new Error('No base64 decoder available')\r\n }\r\n\r\n function evaluateLibrarySource(libraryKey, globalVar, source) {\r\n var registry = ensureExportsRegistry()\r\n if (!source) {\r\n throw new Error('Embedded library source was empty for ' + libraryKey)\r\n }\r\n\r\n var previousValue = window[globalVar]\r\n try {\r\n var executor = new Function(\r\n source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js',\r\n )\r\n executor.call(window)\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to evaluate embedded library ' +\r\n libraryKey +\r\n ': ' +\r\n (error && error.message ? error.message : error),\r\n )\r\n }\r\n\r\n var exported = window[globalVar] || previousValue\r\n if (!exported) {\r\n throw new Error(\r\n 'Embedded library ' + libraryKey + ' did not register ' + globalVar,\r\n )\r\n }\r\n\r\n registry[libraryKey] = exported\r\n return exported\r\n }\r\n\r\n async function ensureLibraryLoaded(config, libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n if (registry[libraryKey]) {\r\n return registry[libraryKey]\r\n }\r\n\r\n var entry = config.manifest && config.manifest[libraryKey]\r\n if (!entry) {\r\n throw new Error('No manifest entry for embedded library ' + libraryKey)\r\n }\r\n\r\n var source = null\r\n if (config.useHost !== false && hasHostBridge()) {\r\n try {\r\n var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey)\r\n source = decodeBase64ToUtf8(base64)\r\n } catch (error) {\r\n // Log the RPC error loudly before fallback\r\n console.error(\r\n '[Venus Libraries] Failed to load ' +\r\n libraryKey +\r\n ' from host via RPC:',\r\n error,\r\n )\r\n console.warn(\r\n '[Venus Libraries] Falling back to CDN for ' +\r\n libraryKey +\r\n '. This may indicate an asset packaging issue.',\r\n )\r\n }\r\n }\r\n\r\n if (!source) {\r\n source = await loadLibraryViaCdn(config, entry, libraryKey)\r\n }\r\n\r\n return evaluateLibrarySource(libraryKey, entry.globalVar, source)\r\n }\r\n\r\n async function bootstrap() {\r\n try {\r\n registerResponseListeners()\r\n getBootstrapPromise()\r\n\r\n var config = ensureConfig()\r\n\r\n if (!config.enabled) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n if (!Array.isArray(config.required) || config.required.length === 0) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n // Group libraries by load stage for parallel loading within stages\r\n var librariesByStage = {}\r\n for (var i = 0; i < config.required.length; i++) {\r\n var libraryKey = config.required[i]\r\n var entry = config.manifest[libraryKey]\r\n var stage = entry.loadStage || 0\r\n if (!librariesByStage[stage]) librariesByStage[stage] = []\r\n librariesByStage[stage].push(libraryKey)\r\n }\r\n\r\n // Load stages sequentially, libraries within each stage in parallel\r\n var stages = Object.keys(librariesByStage).sort(function (a, b) {\r\n return parseInt(a, 10) - parseInt(b, 10)\r\n })\r\n\r\n for (var s = 0; s < stages.length; s++) {\r\n var stage = stages[s]\r\n var libs = librariesByStage[stage]\r\n\r\n // Load all libraries in this stage in parallel\r\n var stagePromises = libs.map(function (libraryKey) {\r\n return ensureLibraryLoaded(config, libraryKey).catch(\r\n function (error) {\r\n console.error(\r\n '[Venus Libraries] Failed to load library ' + libraryKey,\r\n error,\r\n )\r\n throw error\r\n },\r\n )\r\n })\r\n\r\n await Promise.all(stagePromises)\r\n }\r\n\r\n if (bootstrapResolve) bootstrapResolve()\r\n } catch (error) {\r\n console.error('[Venus Libraries] Bootstrap error', error)\r\n if (bootstrapReject) bootstrapReject(error)\r\n throw error\r\n }\r\n }\r\n\r\n // Create a promise that resolves when bootstrap completes\r\n var bootstrapPromise = null\r\n var bootstrapResolve = null\r\n var bootstrapReject = null\r\n\r\n function getBootstrapPromise() {\r\n if (!bootstrapPromise) {\r\n bootstrapPromise = new Promise(function (resolve, reject) {\r\n bootstrapResolve = resolve\r\n bootstrapReject = reject\r\n })\r\n }\r\n return bootstrapPromise\r\n }\r\n\r\n window.__venusLibraryShim = {\r\n bootstrap: bootstrap,\r\n ready: getBootstrapPromise,\r\n getExports: function (libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n return registry[libraryKey]\r\n },\r\n __initialized: true,\r\n }\r\n})()\r\n";
5165
5173
 
5166
5174
  // src/webview/webviewLibraryShimSource.ts