@retion-miniapp/react-native 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -155,10 +155,14 @@ interface MiniAppNativeHandlers {
155
155
  params?: Record<string, unknown>;
156
156
  }, context: MiniAppHandlerContext) => Promise<void> | void;
157
157
  }
158
+ /** Kiểu rung web gửi qua haptic() — trùng tên trigger của react-native-haptic-feedback. */
159
+ type MiniAppHapticType = 'selection' | 'impactLight' | 'impactMedium' | 'impactHeavy' | 'rigid' | 'soft' | 'notificationSuccess' | 'notificationWarning' | 'notificationError';
158
160
  /** Hành vi bridge phụ thuộc ứng dụng. */
159
161
  interface MiniAppBridgeOptions {
160
162
  /** Web gọi showToast(). Không truyền → bỏ qua. */
161
163
  showToast?: (message: string) => void;
164
+ /** Web gọi haptic(type) (lệnh 1 chiều). Không truyền → bỏ qua. */
165
+ haptic?: (type: MiniAppHapticType) => void;
162
166
  /** Web gọi openWebview(url). Mặc định Linking.openURL. */
163
167
  openUrl?: (url: string) => Promise<void> | void;
164
168
  /** Trả cho web qua getSystemInfo(). */
@@ -193,6 +197,12 @@ interface MiniAppConfig {
193
197
  channels: MiniAppChannel[];
194
198
  file_system: MiniAppFileSystem;
195
199
  storage: MiniAppStorage;
200
+ /**
201
+ * app_id cập nhật thủ công (không có trong mảng → tự động cập nhật như mặc định): đã có bản trong máy mà có bản mới → KHÔNG tự tải (kể cả khi mở app), bắn event
202
+ * `update_available` để ứng dụng hiện popup; người dùng bấm → `updateMiniApp(app_id)` tải và dùng bản mới.
203
+ * Chưa có bản nào trong máy → vẫn tải ngay như thường.
204
+ */
205
+ manual_update?: string[];
196
206
  /** Giới hạn WebView sống. Mặc định: không huỷ. */
197
207
  keep_alive?: MiniAppKeepAlive;
198
208
  /** Log tiến trình tải ra console. */
@@ -370,7 +380,19 @@ type MiniAppEvent =
370
380
  type: 'pause_change';
371
381
  paused: boolean;
372
382
  reasons: string[];
383
+ }
384
+ /** App trong config.manual_update có bản mới — chưa tải, chờ updateMiniApp(app_id). */
385
+ | {
386
+ type: 'update_available';
387
+ app_id: string;
388
+ current_version: string;
389
+ next_version: string;
373
390
  };
391
+ interface MiniAppUpdate {
392
+ app_id: string;
393
+ current_version: string;
394
+ next_version: string;
395
+ }
374
396
  /** Manifest từ API list ứng dụng (bundle_url tuyệt đối). */
375
397
  type MiniAppCatalogEntry = MiniAppManifest & {
376
398
  name?: string;
@@ -420,6 +442,14 @@ declare const resumeMiniApp: (app_id: string) => void;
420
442
  declare const pauseMiniAppDownloads: (reason: string) => void;
421
443
  /** Gỡ lý do dừng; hết lý do → chạy tiếp. */
422
444
  declare const resumeMiniAppDownloads: (reason: string) => void;
445
+ /** Bản cập nhật đang chờ của app (config.manual_update) — đọc đồng bộ, vd lúc mount popup (lỡ event). */
446
+ declare const getMiniAppUpdate: (app_id: string) => MiniAppUpdate | undefined;
447
+ /**
448
+ * Cập nhật thủ công (app trong config.manual_update): tải ngay bản mới (bỏ qua pause), bắn status_change(updating) /
449
+ * progress, xong → mọi WebView của app nạp lại bằng bản mới (kể cả đang hiện). true: đã dùng bản mới; false: lỗi,
450
+ * giữ bản cũ và update vẫn chờ.
451
+ */
452
+ declare const updateMiniApp: (app_id: string) => Promise<boolean>;
423
453
  type MiniAppCatalogItem = MiniAppCatalogEntry & {
424
454
  /** Máy đang có 1 bản (có thể cũ). */
425
455
  installed: boolean;
@@ -454,4 +484,4 @@ declare class BridgeError extends Error {
454
484
  constructor(code: string, message: string);
455
485
  }
456
486
 
457
- export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppCatalogItem, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, type MiniAppEvent, type MiniAppFileSystem, type MiniAppHandlerContext, _default as MiniAppHost, type MiniAppHostData, BridgeError as MiniAppHostError, type MiniAppHostProps, type MiniAppKeepAlive, type MiniAppLaunch, type MiniAppLocalBundle, type MiniAppManifest, type MiniAppNativeHandlers, type MiniAppPaymentRequest, type MiniAppPaymentResult, type MiniAppPermission, type MiniAppSplashProps, type MiniAppStorage, type MiniAppSyncResult, type OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalog, getMiniAppCatalogEntry, getMiniAppStatuses, onMiniAppEvent, openMiniApp, pauseMiniApp, pauseMiniAppDownloads, preloadMiniApp, restoreMiniApp, resumeMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
487
+ export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppCatalogItem, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, type MiniAppEvent, type MiniAppFileSystem, type MiniAppHandlerContext, type MiniAppHapticType, _default as MiniAppHost, type MiniAppHostData, BridgeError as MiniAppHostError, type MiniAppHostProps, type MiniAppKeepAlive, type MiniAppLaunch, type MiniAppLocalBundle, type MiniAppManifest, type MiniAppNativeHandlers, type MiniAppPaymentRequest, type MiniAppPaymentResult, type MiniAppPermission, type MiniAppSplashProps, type MiniAppStorage, type MiniAppSyncResult, type MiniAppUpdate, type OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalog, getMiniAppCatalogEntry, getMiniAppStatuses, getMiniAppUpdate, onMiniAppEvent, openMiniApp, pauseMiniApp, pauseMiniAppDownloads, preloadMiniApp, restoreMiniApp, resumeMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, updateMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
package/dist/index.d.ts CHANGED
@@ -155,10 +155,14 @@ interface MiniAppNativeHandlers {
155
155
  params?: Record<string, unknown>;
156
156
  }, context: MiniAppHandlerContext) => Promise<void> | void;
157
157
  }
158
+ /** Kiểu rung web gửi qua haptic() — trùng tên trigger của react-native-haptic-feedback. */
159
+ type MiniAppHapticType = 'selection' | 'impactLight' | 'impactMedium' | 'impactHeavy' | 'rigid' | 'soft' | 'notificationSuccess' | 'notificationWarning' | 'notificationError';
158
160
  /** Hành vi bridge phụ thuộc ứng dụng. */
159
161
  interface MiniAppBridgeOptions {
160
162
  /** Web gọi showToast(). Không truyền → bỏ qua. */
161
163
  showToast?: (message: string) => void;
164
+ /** Web gọi haptic(type) (lệnh 1 chiều). Không truyền → bỏ qua. */
165
+ haptic?: (type: MiniAppHapticType) => void;
162
166
  /** Web gọi openWebview(url). Mặc định Linking.openURL. */
163
167
  openUrl?: (url: string) => Promise<void> | void;
164
168
  /** Trả cho web qua getSystemInfo(). */
@@ -193,6 +197,12 @@ interface MiniAppConfig {
193
197
  channels: MiniAppChannel[];
194
198
  file_system: MiniAppFileSystem;
195
199
  storage: MiniAppStorage;
200
+ /**
201
+ * app_id cập nhật thủ công (không có trong mảng → tự động cập nhật như mặc định): đã có bản trong máy mà có bản mới → KHÔNG tự tải (kể cả khi mở app), bắn event
202
+ * `update_available` để ứng dụng hiện popup; người dùng bấm → `updateMiniApp(app_id)` tải và dùng bản mới.
203
+ * Chưa có bản nào trong máy → vẫn tải ngay như thường.
204
+ */
205
+ manual_update?: string[];
196
206
  /** Giới hạn WebView sống. Mặc định: không huỷ. */
197
207
  keep_alive?: MiniAppKeepAlive;
198
208
  /** Log tiến trình tải ra console. */
@@ -370,7 +380,19 @@ type MiniAppEvent =
370
380
  type: 'pause_change';
371
381
  paused: boolean;
372
382
  reasons: string[];
383
+ }
384
+ /** App trong config.manual_update có bản mới — chưa tải, chờ updateMiniApp(app_id). */
385
+ | {
386
+ type: 'update_available';
387
+ app_id: string;
388
+ current_version: string;
389
+ next_version: string;
373
390
  };
391
+ interface MiniAppUpdate {
392
+ app_id: string;
393
+ current_version: string;
394
+ next_version: string;
395
+ }
374
396
  /** Manifest từ API list ứng dụng (bundle_url tuyệt đối). */
375
397
  type MiniAppCatalogEntry = MiniAppManifest & {
376
398
  name?: string;
@@ -420,6 +442,14 @@ declare const resumeMiniApp: (app_id: string) => void;
420
442
  declare const pauseMiniAppDownloads: (reason: string) => void;
421
443
  /** Gỡ lý do dừng; hết lý do → chạy tiếp. */
422
444
  declare const resumeMiniAppDownloads: (reason: string) => void;
445
+ /** Bản cập nhật đang chờ của app (config.manual_update) — đọc đồng bộ, vd lúc mount popup (lỡ event). */
446
+ declare const getMiniAppUpdate: (app_id: string) => MiniAppUpdate | undefined;
447
+ /**
448
+ * Cập nhật thủ công (app trong config.manual_update): tải ngay bản mới (bỏ qua pause), bắn status_change(updating) /
449
+ * progress, xong → mọi WebView của app nạp lại bằng bản mới (kể cả đang hiện). true: đã dùng bản mới; false: lỗi,
450
+ * giữ bản cũ và update vẫn chờ.
451
+ */
452
+ declare const updateMiniApp: (app_id: string) => Promise<boolean>;
423
453
  type MiniAppCatalogItem = MiniAppCatalogEntry & {
424
454
  /** Máy đang có 1 bản (có thể cũ). */
425
455
  installed: boolean;
@@ -454,4 +484,4 @@ declare class BridgeError extends Error {
454
484
  constructor(code: string, message: string);
455
485
  }
456
486
 
457
- export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppCatalogItem, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, type MiniAppEvent, type MiniAppFileSystem, type MiniAppHandlerContext, _default as MiniAppHost, type MiniAppHostData, BridgeError as MiniAppHostError, type MiniAppHostProps, type MiniAppKeepAlive, type MiniAppLaunch, type MiniAppLocalBundle, type MiniAppManifest, type MiniAppNativeHandlers, type MiniAppPaymentRequest, type MiniAppPaymentResult, type MiniAppPermission, type MiniAppSplashProps, type MiniAppStorage, type MiniAppSyncResult, type OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalog, getMiniAppCatalogEntry, getMiniAppStatuses, onMiniAppEvent, openMiniApp, pauseMiniApp, pauseMiniAppDownloads, preloadMiniApp, restoreMiniApp, resumeMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
487
+ export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppCatalogItem, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, type MiniAppEvent, type MiniAppFileSystem, type MiniAppHandlerContext, type MiniAppHapticType, _default as MiniAppHost, type MiniAppHostData, BridgeError as MiniAppHostError, type MiniAppHostProps, type MiniAppKeepAlive, type MiniAppLaunch, type MiniAppLocalBundle, type MiniAppManifest, type MiniAppNativeHandlers, type MiniAppPaymentRequest, type MiniAppPaymentResult, type MiniAppPermission, type MiniAppSplashProps, type MiniAppStorage, type MiniAppSyncResult, type MiniAppUpdate, type OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalog, getMiniAppCatalogEntry, getMiniAppStatuses, getMiniAppUpdate, onMiniAppEvent, openMiniApp, pauseMiniApp, pauseMiniAppDownloads, preloadMiniApp, restoreMiniApp, resumeMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, updateMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var qt=Object.create;var le=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var Ut=Object.getOwnPropertyNames;var Kt=Object.getPrototypeOf,zt=Object.prototype.hasOwnProperty;var Yt=(e,t)=>{for(var n in t)le(e,n,{get:t[n],enumerable:!0})},qe=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ut(t))!zt.call(e,s)&&s!==n&&le(e,s,{get:()=>t[s],enumerable:!(r=Ht(t,s))||r.enumerable});return e};var He=(e,t,n)=>(n=e!=null?qt(Kt(e)):{},qe(t||!e||!e.__esModule?le(n,"default",{value:e,enumerable:!0}):n,e)),Qt=e=>qe(le({},"__esModule",{value:!0}),e);var fn={};Yt(fn,{DefaultMiniAppSplash:()=>Ne,MINIAPP_PLATFORM_URL:()=>ue,MiniAppHost:()=>$t,MiniAppHostError:()=>E,closeMiniApp:()=>ee,configureMiniApp:()=>Ke,createMmkvStorage:()=>Qe,createRnfsFileSystem:()=>Ye,ensureMiniApp:()=>xe,getLocalMiniApp:()=>T,getMiniAppCatalog:()=>kt,getMiniAppCatalogEntry:()=>ae,getMiniAppStatuses:()=>bt,onMiniAppEvent:()=>_t,openMiniApp:()=>Mt,pauseMiniApp:()=>Rt,pauseMiniAppDownloads:()=>Ct,preloadMiniApp:()=>wt,restoreMiniApp:()=>Tt,resumeMiniApp:()=>Pt,resumeMiniAppDownloads:()=>Ot,sendEventToWeb:()=>At,syncMiniAppCatalog:()=>be,uninstallMiniApp:()=>Et,useMiniAppDownload:()=>Se,useMiniAppDownloadsPaused:()=>St});module.exports=Qt(fn);var ue="https://retion-miniapp-platform.vercel.app",Q=null,Ue=new Set,Ke=e=>{Q=e,Ue.forEach(t=>t())},x=()=>{if(!Q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return Q},ze=e=>{Ue.add(e),Q&&e()},J=(...e)=>{Q!=null&&Q.debug&&console.log("[miniapp]",...e)};var Ye=(e,t)=>({document_dir:e.DocumentDirectoryPath,cache_dir:e.CachesDirectoryPath,exists:n=>e.exists(n),mkdir:n=>e.mkdir(n),remove:n=>e.unlink(n).catch(()=>{}),listDir:n=>e.readDir(n).then(r=>r.map(s=>s.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:s})=>{let{jobId:o,promise:l}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:i,contentLength:p})=>s==null?void 0:s(i,p)});return{promise:l.then(({statusCode:i})=>({status:i})),cancel:()=>e.stopDownload(o)}}}),Qe=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});var u=He(require("react")),w=require("react-native"),Lt=He(require("react-native-webview"));var de=require("react-native"),ge=1,E=class extends Error{constructor(n,r){super(r);this.code=n}},Xe=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===ge&&typeof t.method=="string"?t:null}catch{return null}},fe=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,Ze=(e,t)=>fe({id:e,result:t}),et=(e,t)=>fe({id:e,error:{code:t.code,message:t.message}}),Ce=e=>fe({event:"context",data:e});var tt=()=>`(function () {
1
+ "use strict";var Yt=Object.create;var de=Object.defineProperty;var Qt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var Xt=Object.getPrototypeOf,Zt=Object.prototype.hasOwnProperty;var en=(e,t)=>{for(var n in t)de(e,n,{get:t[n],enumerable:!0})},Ke=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Gt(t))!Zt.call(e,a)&&a!==n&&de(e,a,{get:()=>t[a],enumerable:!(r=Qt(t,a))||r.enumerable});return e};var ze=(e,t,n)=>(n=e!=null?Yt(Xt(e)):{},Ke(t||!e||!e.__esModule?de(n,"default",{value:e,enumerable:!0}):n,e)),tn=e=>Ke(de({},"__esModule",{value:!0}),e);var wn={};en(wn,{DefaultMiniAppSplash:()=>Be,MINIAPP_PLATFORM_URL:()=>ge,MiniAppHost:()=>Ut,MiniAppHostError:()=>T,closeMiniApp:()=>ne,configureMiniApp:()=>Qe,createMmkvStorage:()=>Ze,createRnfsFileSystem:()=>Xe,ensureMiniApp:()=>ce,getLocalMiniApp:()=>S,getMiniAppCatalog:()=>Nt,getMiniAppCatalogEntry:()=>re,getMiniAppStatuses:()=>Rt,getMiniAppUpdate:()=>Ne,onMiniAppEvent:()=>Tt,openMiniApp:()=>vt,pauseMiniApp:()=>Ot,pauseMiniAppDownloads:()=>Dt,preloadMiniApp:()=>_t,restoreMiniApp:()=>kt,resumeMiniApp:()=>It,resumeMiniAppDownloads:()=>Lt,sendEventToWeb:()=>yt,syncMiniAppCatalog:()=>Ee,uninstallMiniApp:()=>Ct,updateMiniApp:()=>$t,useMiniAppDownload:()=>be,useMiniAppDownloadsPaused:()=>Et});module.exports=tn(wn);var ge="https://retion-miniapp-platform.vercel.app",Z=null,Ye=new Set,Qe=e=>{Z=e,Ye.forEach(t=>t())},E=()=>{if(!Z)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return Z},Ge=e=>{Ye.add(e),Z&&e()},N=(...e)=>{Z!=null&&Z.debug&&console.log("[miniapp]",...e)};var Xe=(e,t)=>({document_dir:e.DocumentDirectoryPath,cache_dir:e.CachesDirectoryPath,exists:n=>e.exists(n),mkdir:n=>e.mkdir(n),remove:n=>e.unlink(n).catch(()=>{}),listDir:n=>e.readDir(n).then(r=>r.map(a=>a.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:a})=>{let{jobId:s,promise:c}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:l,contentLength:o})=>a==null?void 0:a(l,o)});return{promise:c.then(({statusCode:l})=>({status:l})),cancel:()=>e.stopDownload(s)}}}),Ze=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});var u=ze(require("react")),w=require("react-native"),Jt=ze(require("react-native-webview"));var fe=require("react-native"),he=1,T=class extends Error{constructor(n,r){super(r);this.code=n}},tt=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===he&&typeof t.method=="string"?t:null}catch{return null}},Ae=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,nt=(e,t)=>Ae({id:e,result:t}),rt=(e,t)=>Ae({id:e,error:{code:t.code,message:t.message}}),ke=e=>Ae({event:"context",data:e});var ot=()=>`(function () {
2
2
  var post = function (level, args) {
3
3
  try {
4
4
  var parts = [];
@@ -8,7 +8,7 @@
8
8
  else if (typeof a === 'object') { try { parts.push(JSON.stringify(a).slice(0, 800)); } catch (e) { parts.push(String(a)); } }
9
9
  else { parts.push(String(a)); }
10
10
  }
11
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${ge}, method: 'log', level: level, text: parts.join(' ') }));
11
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${he}, method: 'log', level: level, text: parts.join(' ') }));
12
12
  } catch (e) {}
13
13
  };
14
14
  ['log', 'info', 'warn', 'error'].forEach(function (level) {
@@ -19,7 +19,7 @@
19
19
  window.addEventListener('unhandledrejection', function (e) { post('error', ['[unhandledrejection]', e.reason]); });
20
20
  // Kh\xF4ng log query (c\xF3 th\u1EC3 ch\u1EE9a token) \u2014 ch\u1EC9 \u0111\u01B0\u1EDDng d\u1EABn + route.
21
21
  post('info', ['[page] ' + location.pathname + location.hash]);
22
- })(); true;`,nt=()=>`(function () {
22
+ })(); true;`,it=()=>`(function () {
23
23
  function atTop(el) {
24
24
  for (var n = el; n && n !== document.documentElement; n = n.parentElement) {
25
25
  if (n.scrollTop > 0) { return false; }
@@ -30,7 +30,7 @@
30
30
  function report(at_top) {
31
31
  if (at_top === last) { return; }
32
32
  last = at_top;
33
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${ge}, method: 'touchAtTop', at_top: at_top }));
33
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${he}, method: 'touchAtTop', at_top: at_top }));
34
34
  }
35
35
  document.addEventListener('touchstart', function (e) { report(atTop(e.target)); }, { capture: true, passive: true });
36
36
  // Cu\u1ED9n r\u1EDDi \u0111\u1EA7u trang \u2192 b\xE1o ngay, kh\xF4ng \u0111\u1EE3i l\u1EA7n ch\u1EA1m sau (tr\xE1nh host d\xF9ng gi\xE1 tr\u1ECB c\u0169 "\u0111ang \u1EDF \u0111\u1EA7u").
@@ -38,8 +38,8 @@
38
38
  var el = e.target === document ? document.documentElement : e.target;
39
39
  if (el && el.scrollTop > 0) { report(false); }
40
40
  }, { capture: true, passive: true });
41
- })(); true;`,rt=e=>fe({event:e}),ot=(e,t)=>{let n=st(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
- ${Ce(e)}`},st=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),it=(e,t={})=>{let n=st(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${ge} };
41
+ })(); true;`,st=e=>Ae({event:e}),at=(e,t)=>{let n=pt(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
+ ${ke(e)}`},pt=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),ct=(e,t={})=>{let n=pt(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${he} };
43
43
  window.__RETION_MINIAPP_CONTEXT__ = ${JSON.stringify(e)};
44
44
  ${n?`try { history.replaceState(history.state, '', location.pathname + '?' + ${JSON.stringify(n)} + location.hash); } catch (e) {}`:""}
45
- true;`},at={partner:"partner_token",chatbox:"chatbox_token"},pt=(e,t)=>{let n={...e};for(let r of Object.values(at))t.includes(r)||delete n[r];return n},Re=new Set,Ge=async(e,t)=>{if(Re.has(e))throw new E("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);Re.add(e);try{return await t()}finally{Re.delete(e)}},Pe=(e,t)=>{if(typeof e!="string"||!e)throw new E("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},ct=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:s,close:o,app_id:l,instance_id:i,options:p})=>{var M,g,D,S;let f=p==null?void 0:p.handlers,A={app_id:l,instance_id:i,close:o},y=()=>new E("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let d=f==null?void 0:f.requestPayment;if(!d)throw y();let a=t==null?void 0:t.amount;if(typeof a!="number"||!Number.isFinite(a)||a<=0)throw new E("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let R={...t,amount:a,currency:Pe(t==null?void 0:t.currency,"currency")};return Ge(e,()=>d(R,A))}case"printImage":{let d=f==null?void 0:f.printImage;if(!d)throw y();let a=Pe(t==null?void 0:t.image,"image");await Ge(e,()=>d({image:a},A));return}case"openScreen":if(!(f!=null&&f.openScreen))throw y();await f.openScreen({screen:Pe(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},A);return;case"closeApp":o();return;case"openWebview":{let d=String((M=t==null?void 0:t.url)!=null?M:"");if(!/^https?:\/\//i.test(d))throw new E("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(p!=null&&p.openUrl?p.openUrl(d):de.Linking.openURL(d));return}case"showToast":(D=p==null?void 0:p.showToast)==null||D.call(p,String((g=t==null?void 0:t.message)!=null?g:""));return;case"getSystemInfo":return{platform:de.Platform.OS==="ios"?"ios":"android",appVersion:(S=p==null?void 0:p.app_version)!=null?S:"",theme:s?"dark":"light"};case"getAccessToken":{let d=n().access_token;if(!d)throw new E("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return d}case"getToken":{let d=t==null?void 0:t.type;if(d==="access"){let q=n().access_token;if(!q)throw new E("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return q}if(d!=="partner"&&d!=="chatbox")throw new E("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(d)}`);let a=at[d];if(!r().includes(a))throw new E("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${a} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let R=d==="partner"?n().partner_token:n().chatbox_token;if(!R)throw new E("HOST_ERROR",`Kh\xF4ng c\xF3 ${a}`);return R}case"getUserInfo":{let d=n().user;if(!d)throw new E("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return d}case"getPageInfo":{let d=n().page;if(!d)throw new E("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return d}case"sendMessage":case"insertText":throw new E("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new E("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var Oe=e=>`bundle:${e}`,ke=()=>`${x().file_system.document_dir}/miniapps`,dt=(e,t,n="index.html",r=!1,s=[])=>{let o=`${ke()}/${e}/${t}`;return{app_id:e,version:t,dir:o,entry_uri:`file://${o}/${n}`,context_update:r,permissions:s}},lt=e=>{var t;x().storage.setString(Oe(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},Gt=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,T=e=>{let t=x().storage.getString(Oe(e));if(!t)return null;try{let{version:n,entry:r,context_update:s,permissions:o}=JSON.parse(t);return dt(e,n,r,!!s,Array.isArray(o)?o:[])}catch{return null}},he=e=>x().file_system.exists(e.entry_uri.replace("file://","")),Ie=async e=>{let t=T(e.app_id);return(t==null?void 0:t.version)===e.version&&await he(t)},Xt=async(e,t)=>{let n=x().file_system,r=`${ke()}/${e}`,s=await n.listDir(r).catch(()=>[]);await Promise.all(s.filter(o=>!t.includes(o)).map(o=>n.remove(`${r}/${o}`).catch(()=>{})))},gt=async e=>{var t;await((t=se[e])==null?void 0:t.catch(()=>{})),x().storage.setString(Oe(e),""),await x().file_system.remove(`${ke()}/${e}`).catch(()=>{})},Z=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},se={},De=(e,{base_url:t,onProgress:n}={})=>{var M;let r=x().file_system,s=null,o=!1,l=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,i=()=>{if(o)throw new Z},p=async()=>{var S;i();let g=T(e.app_id);if((g==null?void 0:g.version)===e.version&&await r.exists(g.dir))return lt(e),T(e.app_id);i();let D=r.download({url:t?Gt(t,e.bundle_url):e.bundle_url,to_file:l,onProgress:(d,a)=>{var q;let R=a>0?a:(q=e.size)!=null?q:0;R>0&&(n==null||n(Math.min(1,d/R)))}});s=D;try{let{status:d}=await D.promise;if(i(),d!==200)throw new Error(`bundle ${d}`);if(e.sha256)if(r.sha256){if(await r.sha256(l)!==e.sha256)throw new Error("sha256 mismatch")}else J("b\u1ECF qua ki\u1EC3m tra sha256 (file_system kh\xF4ng c\xF3 sha256)",e.app_id);i();let a=dt(e.app_id,e.version,e.entry,!!e.context_update,(S=e.permissions)!=null?S:[]);return await r.remove(a.dir).catch(()=>{}),await r.mkdir(a.dir),await r.unzip(l,a.dir),lt(e),Xt(e.app_id,[e.version,g==null?void 0:g.version].filter(Boolean)),a}catch(d){throw o?new Z:d}finally{s=null,r.remove(l).catch(()=>{})}},A=((M=se[e.app_id])!=null?M:Promise.resolve()).catch(()=>{}).then(p),y=A.catch(()=>{});return se[e.app_id]=y,y.then(()=>{se[e.app_id]===y&&delete se[e.app_id]}),{promise:A,cancel:()=>{o=!0,s==null||s.cancel()}}},oe={},Zt=__DEV__?0:60*1e3,ut={},ft=(e,t)=>{var r,s;let n=T(e);return n&&Date.now()-((r=ut[t])!=null?r:0)<Zt?Promise.resolve(n):((s=oe[e])!=null||(oe[e]=(async()=>{let o=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!o.ok)throw new Error(`manifest ${o.status}`);let l=await o.json(),i=await De(l,{base_url:t}).promise;return ut[t]=Date.now(),i})().catch(o=>(console.warn("[miniapp] sync failed",e,o==null?void 0:o.message),T(e))).finally(()=>{oe[e]=void 0})),oe[e])};var Ae=new Map,ht=(e,t)=>(Ae.set(e,t),()=>{Ae.get(e)===t&&Ae.delete(e)}),At=(e,t)=>{let n=Ae.get(e);return n?n(t):!1};var me=require("react"),Me=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let s=typeof r=="function"?r(t):r;t={...t,...s},n.forEach(o=>o())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},W=(e,t,n=Object.is)=>{let r=(0,me.useRef)(null),s=()=>{let o=e.getState(),l=r.current;if(l&&l.state===o&&l.selector===t)return l.value;let i=t(o),p=l&&n(l.value,i)?l.value:i;return r.current={state:o,selector:t,value:p},p};return(0,me.useSyncExternalStore)(e.subscribe,s)};var N=Me({active_key:null,instances:{}}),mt=({app:e,instance_id:t,context:n={},url_params:r={},host_data:s={}},o)=>{var i;let l=(i=x().keep_alive)==null?void 0:i.max_webviews;N.setState(p=>{let f=t!=null?t:e.app_id,A={...p.instances,[f]:{key:f,app:e,context:n,url_params:r,host_data:s,last_used_at:Date.now()}},y=Object.keys(A);return l&&l>0&&y.length>l&&y.filter(M=>M!==f).sort((M,g)=>A[M].last_used_at-A[g].last_used_at).slice(0,y.length-l).forEach(M=>{delete A[M]}),o?{active_key:f,instances:A}:{instances:A}})},Mt=e=>mt(e,!0),wt=e=>mt(e,!1),ee=()=>N.setState({active_key:null}),we=e=>{N.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var yt="catalog",en="paused_apps",tn="removed_apps",nn=10*1e3,rn=2,on=3e3,sn=()=>{var e;try{return JSON.parse((e=x().storage.getString(yt))!=null?e:"{}")}catch{return{}}},b=Me({catalog:{},downloads:{},pause_reasons:[]}),vt=e=>{let t=new Set,n=()=>x().storage.setString(e,JSON.stringify([...t]));return{has:r=>t.has(r),values:()=>[...t],add:r=>t.has(r)?!1:(t.add(r),n(),!0),delete:r=>t.delete(r)?(n(),!0):!1,load:()=>{var r;t.clear();try{let s=JSON.parse((r=x().storage.getString(e))!=null?r:"[]");Array.isArray(s)&&s.forEach(o=>{typeof o=="string"&&t.add(o)})}catch{}}}},F=vt(en),K=vt(tn);ze(()=>{F.load(),K.load();let e=sn(),t={};Object.keys(e).filter(n=>!K.has(n)).forEach(n=>{let r=T(n);r?t[n]={status:"installed",progress:1,version:r.version,has_local:!0}:F.has(n)&&(t[n]={status:"paused",progress:0,version:e[n].version,has_local:!1})}),b.setState({catalog:e,downloads:t})});var Se=e=>W(b,t=>e?t.downloads[e]:void 0),St=()=>W(b,e=>e.pause_reasons.length>0),V=(...e)=>J("queue",...e),P=[],j={},m=null,ye=new Set,G={},Le=new Set,X=e=>{Le.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},_t=e=>(Le.add(e),()=>{Le.delete(e)}),bt=()=>b.getState().downloads,k=(e,t)=>{let n=!!T(e),r=b.getState().downloads[e],s=t.status==="downloading"&&n?"updating":t.status,o={...r!=null?r:{status:"queued",progress:0},...t,...s?{status:s}:{},has_local:n};b.setState(l=>({downloads:{...l.downloads,[e]:o}})),(r==null?void 0:r.status)!==o.status||(r==null?void 0:r.version)!==o.version||(r==null?void 0:r.has_local)!==o.has_local?X({type:"status_change",app_id:e,state:o}):r.progress!==o.progress&&X({type:"progress",app_id:e,progress:o.progress,version:o.version})},ve=(e,t)=>{var n;(n=G[e])==null||n.forEach(r=>r(t)),delete G[e]},an=()=>b.getState().pause_reasons.length>0,U=e=>{var i;if(m)return;let t=e?P.indexOf(e):an()?-1:P.findIndex(p=>!F.has(p));if(t<0||t>=P.length)return;let[n]=P.splice(t,1),r=b.getState().catalog[n];if(!r){ve(n,T(n)),U();return}let s=Date.now();j[n]=((i=j[n])!=null?i:0)+1,k(n,{status:"downloading",progress:0,version:r.version,error:void 0});let o=0,l=De(r,{onProgress:p=>{let f=Math.floor(p*100);f!==o&&(o=f,k(n,{progress:f/100,version:r.version}))}});m={app_id:n,handle:l,forced:!!e},V("start",n,r.version,e?"(forced)":""),l.promise.then(p=>{V("installed",n,r.version,`${Date.now()-s}ms`),k(n,{status:"installed",progress:1,version:r.version}),ve(n,p)}).catch(p=>{var A;if(p instanceof Z){if(ye.has(n))return;V("paused",n),j[n]-=1,P.unshift(n),k(n,{status:F.has(n)?"paused":"queued",progress:0,version:r.version});return}let f=String((A=p==null?void 0:p.message)!=null?A:p);if(console.warn("[miniapp-queue] failed",n,f),j[n]<rn){k(n,{status:"queued",progress:0,version:r.version,error:f}),setTimeout(()=>{var y;P.includes(n)||(m==null?void 0:m.app_id)===n||(P.push(n),U((y=G[n])!=null&&y.length?n:void 0))},on);return}k(n,{status:"failed",progress:0,version:r.version,error:f}),ve(n,T(n))}).finally(()=>{m=null;let p=P.find(f=>{var A;return(A=G[f])==null?void 0:A.length});U(p)})},_e=(e,{front:t=!1}={})=>{if((m==null?void 0:m.app_id)===e)return;let n=P.indexOf(e);if(n>=0){if(!t)return;P.splice(n,1)}t?P.unshift(e):P.push(e)},pn=async e=>{let{host_id:t,client_token:n}=x(),r=new AbortController,s=setTimeout(()=>r.abort(),nn);try{let o=`${ue}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,l=await fetch(o,{headers:{Authorization:`Bearer ${n}`,"Cache-Control":"no-cache"},signal:r.signal});if(!l.ok)throw new Error(`host list ${e} ${l.status}`);return(await l.json()).apps.map(p=>({...p,channel:e}))}finally{clearTimeout(s)}},ie=null,be=()=>(ie!=null||(ie=(async()=>{var t;let e=Date.now();try{let n=await Promise.all(x().channels.map(pn)),r={};[...n].reverse().flat().forEach(i=>{r[i.app_id]=i});let s=Object.keys(b.getState().catalog).filter(i=>!r[i]);x().storage.setString(yt,JSON.stringify(r)),b.setState({catalog:r}),await Promise.all(s.map(i=>xt(i,{by_user:!1}))),s.forEach(i=>K.delete(i));let o=Object.keys(r).filter(i=>!K.has(i)),l=[];for(let i of o.map(p=>r[p]))await Ie(i)?k(i.app_id,{status:"installed",progress:1,version:i.version}):l.push(i);return l.forEach(i=>{j[i.app_id]=0,k(i.app_id,{status:F.has(i.app_id)?"paused":"queued",progress:0,version:i.version,error:void 0}),_e(i.app_id)}),V("catalog",o.length,"apps, outdated",l.map(i=>i.app_id),"removed",s,`${Date.now()-e}ms`),X({type:"sync_complete",app_ids:o,removed:s}),U(),{ok:!0,app_ids:o,removed:s}}catch(n){let r=String((n==null?void 0:n.name)==="AbortError"?"timeout":(t=n==null?void 0:n.message)!=null?t:n);return console.warn("[miniapp-queue] sync catalog failed",r),X({type:"sync_failed",error:r}),{ok:!1,error:r}}finally{ie=null}})()),ie),xt=async(e,{by_user:t})=>{var s,o,l,i;if(t&&K.add(e),ye.has(e))return;ye.add(e),F.delete(e);let n=P.indexOf(e);n>=0&&P.splice(n,1),(m==null?void 0:m.app_id)===e&&m.handle.cancel();let r=(i=(l=(s=b.getState().downloads[e])==null?void 0:s.version)!=null?l:(o=T(e))==null?void 0:o.version)!=null?i:"";k(e,{status:"uninstalling",progress:0,version:r}),await gt(e),we(e),b.setState(p=>{let f={...p.downloads};return delete f[e],{downloads:f}}),delete j[e],ye.delete(e),ve(e,null),V("uninstalled",e,t?"(user)":"(not in list)"),X({type:"uninstalled",app_id:e})},Et=e=>xt(e,{by_user:!0}),Tt=e=>{let t=ae(e);return t?(K.delete(e),(m==null?void 0:m.app_id)===e||P.includes(e)||(j[e]=0,k(e,{status:F.has(e)?"paused":"queued",progress:0,version:t.version,error:void 0}),_e(e),U(),V("restore",e)),!0):!1},Rt=e=>{if(F.has(e))return;if(F.add(e),V("pause app",e),(m==null?void 0:m.app_id)===e&&!m.forced){m.handle.cancel();return}let t=b.getState().downloads[e];P.includes(e)&&t&&k(e,{status:"paused",progress:0,version:t.version})},Pt=e=>{if(!F.delete(e))return;V("resume app",e);let t=b.getState().downloads[e];(t==null?void 0:t.status)==="paused"&&!P.includes(e)&&ae(e)&&(j[e]=0,_e(e)),P.includes(e)&&t&&k(e,{status:"queued",progress:0,version:t.version}),U()},Ct=e=>{let{pause_reasons:t}=b.getState();t.includes(e)||(b.setState({pause_reasons:[...t,e]}),V("pause",e),t.length===0&&X({type:"pause_change",paused:!0,reasons:[e]}),m&&!m.forced&&m.handle.cancel())},Ot=e=>{let{pause_reasons:t}=b.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);b.setState({pause_reasons:n}),V("resume",e),n.length===0&&X({type:"pause_change",paused:!1,reasons:n}),U()},kt=()=>Object.values(b.getState().catalog).map(e=>({...e,installed:!!T(e.app_id),removed_by_user:K.has(e.app_id)})),ae=e=>b.getState().catalog[e],xe=async e=>{let t=ae(e);if(!t)return;if(F.delete(e),K.delete(e),await Ie(t))return T(e);let n=new Promise(r=>{var s;((s=G[e])!=null?s:G[e]=[]).push(r)});return(m==null?void 0:m.app_id)===e?m.forced=!0:(j[e]=0,_e(e,{front:!0}),m&&!m.forced?m.handle.cancel():U(e)),n};var v=require("react/jsx-runtime"),$e=e=>(e!=null?e:"").replace(/\?[^#]*/,""),It=0,cn=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},ln=u.default.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:s,web_at_top:o,splash:l,bridge:i,opaque_background:p,onWebLoadEnd:f})=>{var We,je;let A=(0,u.useRef)(null),y=(0,u.useRef)(!1),M=W(N,c=>c.instances[e]),g=M==null?void 0:M.app.app_id,D=M==null?void 0:M.app.manifest_url,S=M==null?void 0:M.context,d=M==null?void 0:M.url_params,[a,R]=(0,u.useState)(()=>g?T(g):null),[q,te]=(0,u.useState)(!1),[Nt,Fe]=(0,u.useState)(0),[Ft,ne]=(0,u.useState)(0),[Bt,L]=(0,u.useState)(!1),B=(0,u.useRef)(null),Be=c=>{B.current&&clearTimeout(B.current),B.current=setTimeout(()=>{B.current=null,L(!0)},c)};(0,u.useEffect)(()=>()=>{B.current&&clearTimeout(B.current)},[]),(0,u.useEffect)(()=>{if(!g||!t&&a)return;let c=!0;return te(!1),(async()=>{let h=T(g),C=h?await he(h):!1;if(!c||(R(C?$=>!$||$.version!==h.version||$.permissions.join(",")!==h.permissions.join(",")?h:$:null),__DEV__&&Date.now()-It>1e4&&(It=Date.now(),await be()),!c))return;let H=await xe(g),z=H!==void 0?H:D?await ft(g,D):T(g);if(c){if(!z){te(!0);return}R($=>$!=null?$:z)}})(),()=>{c=!1}},[t,g,D,Nt]),(0,u.useEffect)(()=>ht(e,c=>A.current?(A.current.postMessage(c),!0):!1),[e]);let Jt=W(b,c=>{let h=g?c.downloads[g]:void 0;return(h==null?void 0:h.status)==="installed"?h.version:void 0});(0,u.useEffect)(()=>{if(t||!g||!a)return;let c=T(g);if(!c||c.version===a.version)return;let h=!0;return he(c).then(C=>{!h||!C||(J(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",a.version,"\u2192",c.version),R(c))}),()=>{h=!1}},[t,g,Jt,a==null?void 0:a.version]),(0,u.useEffect)(()=>{var C;let c=(C=x().keep_alive)==null?void 0:C.idle_close_ms;if(t||!c||c<=0)return;let h=setTimeout(()=>{we(e)},c);return()=>clearTimeout(h)},[t,e]),(0,u.useEffect)(()=>{s>0&&(te(!1),L(!1),ne(c=>c+1),Fe(c=>c+1))},[s]);let Je=(0,u.useRef)(t);(0,u.useEffect)(()=>{var c;Je.current!==t&&(Je.current=t,y.current&&((c=A.current)==null||c.injectJavaScript(rt(t?"resumed":"paused"))))},[t]);let pe=`${(We=a==null?void 0:a.version)!=null?We:"none"}:${(je=a==null?void 0:a.permissions.join(","))!=null?je:""}:${Ft}`,re=(0,u.useMemo)(()=>JSON.stringify([S!=null?S:{},d!=null?d:{}]),[S,d]),Ee=(0,u.useMemo)(()=>{var c;return pt(d!=null?d:{},(c=a==null?void 0:a.permissions)!=null?c:[])},[re,a==null?void 0:a.permissions]),Vt=(0,u.useMemo)(()=>it(S!=null?S:{},Ee)+nt()+(x().debug?tt():""),[Ee]),ce=(0,u.useRef)(null),Ve=(0,u.useRef)(null);(0,u.useEffect)(()=>{var h,C,H;if(!a)return;if(Ve.current!==pe){Ve.current=pe,ce.current=re;return}if(ce.current===re)return;let c=((C=JSON.parse((h=ce.current)!=null?h:"[]")[0])!=null?C:{}).org_id;if(ce.current=re,c===(S==null?void 0:S.org_id)&&y.current){L(!1),Be(1500),(H=A.current)==null||H.injectJavaScript(ot(S!=null?S:{},Ee));return}L(!1),ne(z=>z+1)},[re,a,pe]);let Wt=(0,u.useCallback)(async c=>{var C,H,z,$,Te;let h=Xe(c.nativeEvent.data);if(!h){if(g&&(i!=null&&i.onWebEvent))try{Promise.resolve(i.onWebEvent(c.nativeEvent.data,{app_id:g,instance_id:e})).catch(_=>{console.warn("[miniapp] onWebEvent l\u1ED7i",g,_)})}catch(_){console.warn("[miniapp] onWebEvent l\u1ED7i",g,_)}return}if(h.method==="log"){let{level:_,text:O}=h;J(`web:${e}`,_!=null?_:"log",O!=null?O:"");return}if(h.method==="pong"){B.current||L(!0);return}if(h.method==="touchAtTop"){o.emit(!!h.at_top);return}if(h.method==="contextApplied"){B.current&&clearTimeout(B.current),B.current=null,L(!0);return}if(h.method==="ready"){y.current=!0,L(!0);let _=(C=N.getState().instances[e])==null?void 0:C.context;_&&((H=A.current)==null||H.injectJavaScript(Ce(_)));return}try{let _=await ct(h,{getHostData:()=>{var O,Y;return(Y=(O=N.getState().instances[e])==null?void 0:O.host_data)!=null?Y:{}},getPermissions:()=>{var O,Y;return g?(Y=(O=T(g))==null?void 0:O.permissions)!=null?Y:[]:[]},is_dark:r,close:ee,app_id:g!=null?g:"",instance_id:e,options:i});h.id&&((z=A.current)==null||z.injectJavaScript(Ze(h.id,_)))}catch(_){if(!h.id)return;let O=_==null?void 0:_.code,Y=_ instanceof E?_:new E(typeof O=="string"?O:"HOST_ERROR",String(($=_==null?void 0:_.message)!=null?$:_));(Te=A.current)==null||Te.injectJavaScript(et(h.id,Y))}},[e,r,g,o,i]),jt=(0,u.useCallback)(()=>{te(!1),ne(c=>c+1),Fe(c=>c+1)},[]);return(0,v.jsxs)(w.View,{style:[w.StyleSheet.absoluteFill,p&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&I.behind],pointerEvents:t?"auto":"none",children:[a?(0,v.jsx)(Lt.default,{ref:A,source:{uri:a.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${a.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:Vt,onMessage:Wt,bounces:!1,overScrollMode:"never",onLoadStart:c=>{J(`webview:${e}`,"load start",$e(c.nativeEvent.url)),y.current=!1,L(!1)},onError:c=>{J(`webview:${e}`,"load error",$e(c.nativeEvent.url),c.nativeEvent.description),te(!0),L(!1)},onLoadEnd:c=>{let h=c.nativeEvent.url;J(`webview:${e}`,"load end",$e(h)),g&&(f==null||f({app_id:g,instance_id:e,url:h})),Be(1500)},onContentProcessDidTerminate:()=>{y.current=!1,L(!1),ne(c=>c+1)},onRenderProcessGone:()=>(y.current=!1,L(!1),ne(c=>c+1),!0),style:I.webview},pe):null,M&&(0,v.jsx)(dn,{visible:!a||!Bt,interactive:q,children:(0,v.jsx)(un,{splash:l,app:M.app,is_dark:r,error:q,has_bundle:!!a,retry:jt})})]})}),un=u.default.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:s,retry:o})=>{let l=e,i=Se(t.app_id),p=r?"error":!s&&(i==null?void 0:i.status)==="downloading"?"downloading":"loading";return(0,v.jsx)(l,{app:t,is_dark:n,status:p,progress:p==="downloading"?i==null?void 0:i.progress:void 0,retry:o})}),dn=({visible:e,interactive:t,children:n})=>{let r=(0,u.useRef)(new w.Animated.Value(e?1:0)).current,[s,o]=(0,u.useState)(e);return(0,u.useEffect)(()=>{if(e){o(!0),r.setValue(1);return}let l=w.Animated.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return l.start(({finished:i})=>{i&&o(!1)}),()=>l.stop()},[e,r]),s?(0,v.jsx)(w.Animated.View,{style:[w.StyleSheet.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},Ne=({app:e,is_dark:t,status:n,progress:r,retry:s})=>{let o=t?"#FAFAFA":"#18181B";return(0,v.jsxs)(w.View,{style:[I.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[(0,v.jsx)(w.View,{style:[I.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?(0,v.jsx)(w.Image,{source:{uri:e.icon},style:I.splash_icon_image}):(0,v.jsx)(w.Text,{style:I.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),(0,v.jsx)(w.Text,{style:[I.splash_name,{color:o}],children:e.name}),n==="error"?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(w.Text,{style:I.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),(0,v.jsx)(w.TouchableOpacity,{activeOpacity:.7,style:[I.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:s,children:(0,v.jsx)(w.Text,{style:[I.retry_text,{color:o}],children:"Th\u1EED l\u1EA1i"})})]}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(w.ActivityIndicator,{style:I.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&(0,v.jsxs)(w.Text,{style:I.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},Dt=(e,t)=>{let n=(0,u.useRef)(t),r=(0,u.useRef)(!1);__DEV__&&!r.current&&n.current!==t&&(r.current=!0,console.warn(`[miniapp] MiniAppHost prop "${e}" \u0111\u1ED5i gi\u1EEFa c\xE1c l\u1EA7n render \u2192 m\u1ECDi WebView b\u1ECB mount l\u1EA1i. Khai b\xE1o component b\xEAn ngo\xE0i render.`))},gn=({container:e,splash:t=Ne,is_dark:n=!1,bridge:r,close_on_back:s=!0,opaque_background:o=!0,onWebLoadEnd:l})=>{Dt("container",e),Dt("splash",t);let i=e,p=W(N,a=>a.active_key),f=(0,u.useRef)(p);p&&(f.current=p);let A=W(N,a=>Object.keys(a.instances).join("|")),y=W(N,a=>{var R;return a.active_key?(R=a.instances[a.active_key])==null?void 0:R.app.name:void 0}),M=(0,u.useMemo)(()=>A?A.split("|"):[],[A]),[g,D]=(0,u.useState)({}),S=(0,u.useRef)(cn()).current;(0,u.useEffect)(()=>{if(!p||!s)return;let a=w.BackHandler.addEventListener("hardwareBackPress",()=>(ee(),!0));return()=>a.remove()},[p,s]);let d=(0,u.useCallback)(()=>{let a=N.getState().active_key;a&&D(R=>({...R,[a]:(R[a]||0)+1}))},[]);return M.length?(0,v.jsx)(i,{visible:!!p,title:y!=null?y:"",is_dark:n,close:ee,reload:d,subscribeWebAtTop:S.subscribe,children:M.map(a=>(0,v.jsx)(ln,{instance_key:a,is_active:p===a,is_front:(p!=null?p:f.current)===a,is_dark:n,reload_tick:g[a]||0,web_at_top:S,splash:t,bridge:r,opaque_background:o,onWebLoadEnd:l},a))}):null},I=w.StyleSheet.create({webview:{flex:1,backgroundColor:"transparent"},behind:{zIndex:-1},splash:{flex:1,alignItems:"center",justifyContent:"center",gap:12},splash_icon:{width:72,height:72,borderRadius:20,alignItems:"center",justifyContent:"center",overflow:"hidden"},splash_icon_image:{width:72,height:72},splash_letter:{fontSize:28,fontWeight:"700",color:"#1D4ED8"},splash_name:{fontSize:16,fontWeight:"600"},splash_hint:{color:"#71717A"},splash_spinner:{marginTop:8},retry_button:{marginTop:4,paddingHorizontal:20,paddingVertical:10,borderRadius:999},retry_text:{fontWeight:"600"}}),$t=u.default.memo(gn);0&&(module.exports={DefaultMiniAppSplash,MINIAPP_PLATFORM_URL,MiniAppHost,MiniAppHostError,closeMiniApp,configureMiniApp,createMmkvStorage,createRnfsFileSystem,ensureMiniApp,getLocalMiniApp,getMiniAppCatalog,getMiniAppCatalogEntry,getMiniAppStatuses,onMiniAppEvent,openMiniApp,pauseMiniApp,pauseMiniAppDownloads,preloadMiniApp,restoreMiniApp,resumeMiniApp,resumeMiniAppDownloads,sendEventToWeb,syncMiniAppCatalog,uninstallMiniApp,useMiniAppDownload,useMiniAppDownloadsPaused});
45
+ true;`},lt={partner:"partner_token",chatbox:"chatbox_token"},ut=(e,t)=>{let n={...e};for(let r of Object.values(lt))t.includes(r)||delete n[r];return n},Pe=new Set,et=async(e,t)=>{if(Pe.has(e))throw new T("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);Pe.add(e);try{return await t()}finally{Pe.delete(e)}},nn=new Set(["selection","impactLight","impactMedium","impactHeavy","rigid","soft","notificationSuccess","notificationWarning","notificationError"]),Ce=(e,t)=>{if(typeof e!="string"||!e)throw new T("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},dt=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:a,close:s,app_id:c,instance_id:l,options:o})=>{var m,d,L,b,R;let g=o==null?void 0:o.handlers,h={app_id:c,instance_id:l,close:s},v=()=>new T("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let i=g==null?void 0:g.requestPayment;if(!i)throw v();let M=t==null?void 0:t.amount;if(typeof M!="number"||!Number.isFinite(M)||M<=0)throw new T("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let U={...t,amount:M,currency:Ce(t==null?void 0:t.currency,"currency")};return et(e,()=>i(U,h))}case"printImage":{let i=g==null?void 0:g.printImage;if(!i)throw v();let M=Ce(t==null?void 0:t.image,"image");await et(e,()=>i({image:M},h));return}case"openScreen":if(!(g!=null&&g.openScreen))throw v();await g.openScreen({screen:Ce(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},h);return;case"closeApp":s();return;case"openWebview":{let i=String((m=t==null?void 0:t.url)!=null?m:"");if(!/^https?:\/\//i.test(i))throw new T("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(o!=null&&o.openUrl?o.openUrl(i):fe.Linking.openURL(i));return}case"showToast":(L=o==null?void 0:o.showToast)==null||L.call(o,String((d=t==null?void 0:t.message)!=null?d:""));return;case"haptic":{let i=nn.has(t==null?void 0:t.type)?t.type:"selection";(b=o==null?void 0:o.haptic)==null||b.call(o,i);return}case"getSystemInfo":return{platform:fe.Platform.OS==="ios"?"ios":"android",appVersion:(R=o==null?void 0:o.app_version)!=null?R:"",theme:a?"dark":"light"};case"getAccessToken":{let i=n().access_token;if(!i)throw new T("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return i}case"getToken":{let i=t==null?void 0:t.type;if(i==="access"){let j=n().access_token;if(!j)throw new T("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return j}if(i!=="partner"&&i!=="chatbox")throw new T("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(i)}`);let M=lt[i];if(!r().includes(M))throw new T("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${M} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let U=i==="partner"?n().partner_token:n().chatbox_token;if(!U)throw new T("HOST_ERROR",`Kh\xF4ng c\xF3 ${M}`);return U}case"getUserInfo":{let i=n().user;if(!i)throw new T("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return i}case"getPageInfo":{let i=n().page;if(!i)throw new T("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return i}case"sendMessage":case"insertText":throw new T("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new T("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var Oe=e=>`bundle:${e}`,Ie=()=>`${E().file_system.document_dir}/miniapps`,ht=(e,t,n="index.html",r=!1,a=[])=>{let s=`${Ie()}/${e}/${t}`;return{app_id:e,version:t,dir:s,entry_uri:`file://${s}/${n}`,context_update:r,permissions:a}},gt=e=>{var t;E().storage.setString(Oe(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},rn=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,S=e=>{let t=E().storage.getString(Oe(e));if(!t)return null;try{let{version:n,entry:r,context_update:a,permissions:s}=JSON.parse(t);return ht(e,n,r,!!a,Array.isArray(s)?s:[])}catch{return null}},K=e=>E().file_system.exists(e.entry_uri.replace("file://","")),De=async e=>{let t=S(e.app_id);return(t==null?void 0:t.version)===e.version&&await K(t)},on=async(e,t)=>{let n=E().file_system,r=`${Ie()}/${e}`,a=await n.listDir(r).catch(()=>[]);await Promise.all(a.filter(s=>!t.includes(s)).map(s=>n.remove(`${r}/${s}`).catch(()=>{})))},At=async e=>{var t;await((t=ae[e])==null?void 0:t.catch(()=>{})),E().storage.setString(Oe(e),""),await E().file_system.remove(`${Ie()}/${e}`).catch(()=>{})},te=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},ae={},Le=(e,{base_url:t,onProgress:n}={})=>{var m;let r=E().file_system,a=null,s=!1,c=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,l=()=>{if(s)throw new te},o=async()=>{var b;l();let d=S(e.app_id);if((d==null?void 0:d.version)===e.version&&await r.exists(d.dir))return gt(e),S(e.app_id);l();let L=r.download({url:t?rn(t,e.bundle_url):e.bundle_url,to_file:c,onProgress:(R,i)=>{var U;let M=i>0?i:(U=e.size)!=null?U:0;M>0&&(n==null||n(Math.min(1,R/M)))}});a=L;try{let{status:R}=await L.promise;if(l(),R!==200)throw new Error(`bundle ${R}`);if(e.sha256)if(r.sha256){if(await r.sha256(c)!==e.sha256)throw new Error("sha256 mismatch")}else N("b\u1ECF qua ki\u1EC3m tra sha256 (file_system kh\xF4ng c\xF3 sha256)",e.app_id);l();let i=ht(e.app_id,e.version,e.entry,!!e.context_update,(b=e.permissions)!=null?b:[]);return await r.remove(i.dir).catch(()=>{}),await r.mkdir(i.dir),await r.unzip(c,i.dir),gt(e),on(e.app_id,[e.version,d==null?void 0:d.version].filter(Boolean)),i}catch(R){throw s?new te:R}finally{a=null,r.remove(c).catch(()=>{})}},h=((m=ae[e.app_id])!=null?m:Promise.resolve()).catch(()=>{}).then(o),v=h.catch(()=>{});return ae[e.app_id]=v,v.then(()=>{ae[e.app_id]===v&&delete ae[e.app_id]}),{promise:h,cancel:()=>{s=!0,a==null||a.cancel()}}},se={},sn=__DEV__?0:60*1e3,ft={},mt=(e,t)=>{var r,a;let n=S(e);return n&&Date.now()-((r=ft[t])!=null?r:0)<sn?Promise.resolve(n):((a=se[e])!=null||(se[e]=(async()=>{let s=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!s.ok)throw new Error(`manifest ${s.status}`);let c=await s.json(),l=await Le(c,{base_url:t}).promise;return ft[t]=Date.now(),l})().catch(s=>(console.warn("[miniapp] sync failed",e,s==null?void 0:s.message),S(e))).finally(()=>{se[e]=void 0})),se[e])};var me=new Map,Mt=(e,t)=>(me.set(e,t),()=>{me.get(e)===t&&me.delete(e)}),yt=(e,t)=>{let n=me.get(e);return n?n(t):!1};var Me=require("react"),ye=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let a=typeof r=="function"?r(t):r;t={...t,...a},n.forEach(s=>s())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},H=(e,t,n=Object.is)=>{let r=(0,Me.useRef)(null),a=()=>{let s=e.getState(),c=r.current;if(c&&c.state===s&&c.selector===t)return c.value;let l=t(s),o=c&&n(c.value,l)?c.value:l;return r.current={state:s,selector:t,value:o},o};return(0,Me.useSyncExternalStore)(e.subscribe,a)};var F=ye({active_key:null,instances:{}}),wt=({app:e,instance_id:t,context:n={},url_params:r={},host_data:a={}},s)=>{var l;let c=(l=E().keep_alive)==null?void 0:l.max_webviews;F.setState(o=>{let g=t!=null?t:e.app_id,h={...o.instances,[g]:{key:g,app:e,context:n,url_params:r,host_data:a,last_used_at:Date.now()}},v=Object.keys(h);return c&&c>0&&v.length>c&&v.filter(m=>m!==g).sort((m,d)=>h[m].last_used_at-h[d].last_used_at).slice(0,v.length-c).forEach(m=>{delete h[m]}),s?{active_key:g,instances:h}:{instances:h}})},vt=e=>wt(e,!0),_t=e=>wt(e,!1),ne=()=>F.setState({active_key:null}),we=e=>{F.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var St="catalog",an="paused_apps",pn="removed_apps",cn=10*1e3,ln=2,un=3e3,dn=()=>{var e;try{return JSON.parse((e=E().storage.getString(St))!=null?e:"{}")}catch{return{}}},y=ye({catalog:{},downloads:{},pause_reasons:[],updates:{},apply_ticks:{}}),bt=e=>{var t;return!!((t=E().manual_update)!=null&&t.includes(e))},Se=new Set,xt=e=>{let t=new Set,n=()=>E().storage.setString(e,JSON.stringify([...t]));return{has:r=>t.has(r),values:()=>[...t],add:r=>t.has(r)?!1:(t.add(r),n(),!0),delete:r=>t.delete(r)?(n(),!0):!1,load:()=>{var r;t.clear();try{let a=JSON.parse((r=E().storage.getString(e))!=null?r:"[]");Array.isArray(a)&&a.forEach(s=>{typeof s=="string"&&t.add(s)})}catch{}}}},J=xt(an),Q=xt(pn);Ge(()=>{J.load(),Q.load();let e=dn(),t={};Object.keys(e).filter(n=>!Q.has(n)).forEach(n=>{let r=S(n);r?t[n]={status:"installed",progress:1,version:r.version,has_local:!0}:J.has(n)&&(t[n]={status:"paused",progress:0,version:e[n].version,has_local:!1})}),y.setState({catalog:e,downloads:t})});var be=e=>H(y,t=>e?t.downloads[e]:void 0),Et=()=>H(y,e=>e.pause_reasons.length>0),B=(...e)=>N("queue",...e),P=[],W={},A=null,ve=new Set,ee={},$e=new Set,z=e=>{$e.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},Tt=e=>($e.add(e),()=>{$e.delete(e)}),Rt=()=>y.getState().downloads,k=(e,t)=>{let n=!!S(e),r=y.getState().downloads[e],a=t.status==="downloading"&&n?"updating":t.status,s={...r!=null?r:{status:"queued",progress:0},...t,...a?{status:a}:{},has_local:n};y.setState(c=>({downloads:{...c.downloads,[e]:s}})),(r==null?void 0:r.status)!==s.status||(r==null?void 0:r.version)!==s.version||(r==null?void 0:r.has_local)!==s.has_local?z({type:"status_change",app_id:e,state:s}):r.progress!==s.progress&&z({type:"progress",app_id:e,progress:s.progress,version:s.version})},_e=(e,t)=>{var n;(n=ee[e])==null||n.forEach(r=>r(t)),delete ee[e]},gn=()=>y.getState().pause_reasons.length>0,Y=e=>{var l;if(A)return;let t=e?P.indexOf(e):gn()?-1:P.findIndex(o=>!J.has(o));if(t<0||t>=P.length)return;let[n]=P.splice(t,1),r=y.getState().catalog[n];if(!r){_e(n,S(n)),Y();return}let a=Date.now();W[n]=((l=W[n])!=null?l:0)+1,k(n,{status:"downloading",progress:0,version:r.version,error:void 0});let s=0,c=Le(r,{onProgress:o=>{let g=Math.floor(o*100);g!==s&&(s=g,k(n,{progress:g/100,version:r.version}))}});A={app_id:n,handle:c,forced:!!e},B("start",n,r.version,e?"(forced)":""),c.promise.then(o=>{B("installed",n,r.version,`${Date.now()-a}ms`),k(n,{status:"installed",progress:1,version:r.version}),_e(n,o)}).catch(o=>{var h;if(o instanceof te){if(ve.has(n))return;B("paused",n),W[n]-=1,P.unshift(n),k(n,{status:J.has(n)?"paused":"queued",progress:0,version:r.version});return}let g=String((h=o==null?void 0:o.message)!=null?h:o);if(console.warn("[miniapp-queue] failed",n,g),W[n]<ln){k(n,{status:"queued",progress:0,version:r.version,error:g}),setTimeout(()=>{var v;P.includes(n)||(A==null?void 0:A.app_id)===n||(P.push(n),Y((v=ee[n])!=null&&v.length?n:void 0))},un);return}k(n,{status:"failed",progress:0,version:r.version,error:g}),_e(n,S(n))}).finally(()=>{A=null;let o=P.find(g=>{var h;return(h=ee[g])==null?void 0:h.length});Y(o)})},xe=(e,{front:t=!1}={})=>{if((A==null?void 0:A.app_id)===e)return;let n=P.indexOf(e);if(n>=0){if(!t)return;P.splice(n,1)}t?P.unshift(e):P.push(e)},fn=async e=>{let{host_id:t,client_token:n}=E(),r=new AbortController,a=setTimeout(()=>r.abort(),cn);try{let s=`${ge}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,c=await fetch(s,{headers:{Authorization:`Bearer ${n}`,"Cache-Control":"no-cache"},signal:r.signal});if(!c.ok)throw new Error(`host list ${e} ${c.status}`);return(await c.json()).apps.map(o=>({...o,channel:e}))}finally{clearTimeout(a)}},pe=null,Ee=()=>(pe!=null||(pe=(async()=>{var t;let e=Date.now();try{let n=await Promise.all(E().channels.map(fn)),r={};[...n].reverse().flat().forEach(o=>{r[o.app_id]=o});let a=Object.keys(y.getState().catalog).filter(o=>!r[o]);E().storage.setString(St,JSON.stringify(r)),y.setState({catalog:r}),await Promise.all(a.map(o=>Pt(o,{by_user:!1}))),a.forEach(o=>Q.delete(o));let s=Object.keys(r).filter(o=>!Q.has(o)),c=[],l={};for(let o of s.map(g=>r[g])){if(await De(o)){k(o.app_id,{status:"installed",progress:1,version:o.version});continue}let g=S(o.app_id);if(bt(o.app_id)&&!Se.has(o.app_id)&&g&&await K(g)){k(o.app_id,{status:"installed",progress:1,version:g.version}),l[o.app_id]={app_id:o.app_id,current_version:g.version,next_version:o.version};continue}c.push(o)}return y.setState({updates:l}),c.forEach(o=>{W[o.app_id]=0,k(o.app_id,{status:J.has(o.app_id)?"paused":"queued",progress:0,version:o.version,error:void 0}),xe(o.app_id)}),B("catalog",s.length,"apps, outdated",c.map(o=>o.app_id),"removed",a,`${Date.now()-e}ms`),z({type:"sync_complete",app_ids:s,removed:a}),Object.values(l).forEach(o=>z({type:"update_available",...o})),Y(),{ok:!0,app_ids:s,removed:a}}catch(n){let r=String((n==null?void 0:n.name)==="AbortError"?"timeout":(t=n==null?void 0:n.message)!=null?t:n);return console.warn("[miniapp-queue] sync catalog failed",r),z({type:"sync_failed",error:r}),{ok:!1,error:r}}finally{pe=null}})()),pe),Pt=async(e,{by_user:t})=>{var a,s,c,l;if(t&&Q.add(e),ve.has(e))return;ve.add(e),J.delete(e);let n=P.indexOf(e);n>=0&&P.splice(n,1),(A==null?void 0:A.app_id)===e&&A.handle.cancel();let r=(l=(c=(a=y.getState().downloads[e])==null?void 0:a.version)!=null?c:(s=S(e))==null?void 0:s.version)!=null?l:"";k(e,{status:"uninstalling",progress:0,version:r}),await At(e),we(e),y.setState(o=>{let g={...o.downloads};return delete g[e],{downloads:g}}),delete W[e],ve.delete(e),_e(e,null),B("uninstalled",e,t?"(user)":"(not in list)"),z({type:"uninstalled",app_id:e})},Ct=e=>Pt(e,{by_user:!0}),kt=e=>{let t=re(e);return t?(Q.delete(e),(A==null?void 0:A.app_id)===e||P.includes(e)||(W[e]=0,k(e,{status:J.has(e)?"paused":"queued",progress:0,version:t.version,error:void 0}),xe(e),Y(),B("restore",e)),!0):!1},Ot=e=>{if(J.has(e))return;if(J.add(e),B("pause app",e),(A==null?void 0:A.app_id)===e&&!A.forced){A.handle.cancel();return}let t=y.getState().downloads[e];P.includes(e)&&t&&k(e,{status:"paused",progress:0,version:t.version})},It=e=>{if(!J.delete(e))return;B("resume app",e);let t=y.getState().downloads[e];(t==null?void 0:t.status)==="paused"&&!P.includes(e)&&re(e)&&(W[e]=0,xe(e)),P.includes(e)&&t&&k(e,{status:"queued",progress:0,version:t.version}),Y()},Dt=e=>{let{pause_reasons:t}=y.getState();t.includes(e)||(y.setState({pause_reasons:[...t,e]}),B("pause",e),t.length===0&&z({type:"pause_change",paused:!0,reasons:[e]}),A&&!A.forced&&A.handle.cancel())},Lt=e=>{let{pause_reasons:t}=y.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);y.setState({pause_reasons:n}),B("resume",e),n.length===0&&z({type:"pause_change",paused:!1,reasons:n}),Y()},Ne=e=>y.getState().updates[e],$t=async e=>{var n,r;let t=Ne(e);Se.add(e);try{let a=await ce(e),s=(r=t==null?void 0:t.next_version)!=null?r:(n=re(e))==null?void 0:n.version;return!a||!s||a.version!==s?!1:(y.setState(c=>{var o;let l={...c.updates};return delete l[e],{updates:l,apply_ticks:{...c.apply_ticks,[e]:((o=c.apply_ticks[e])!=null?o:0)+1}}}),B("updated",e,t==null?void 0:t.current_version,"\u2192",a.version),!0)}finally{Se.delete(e)}},Nt=()=>Object.values(y.getState().catalog).map(e=>({...e,installed:!!S(e.app_id),removed_by_user:Q.has(e.app_id)})),re=e=>y.getState().catalog[e],ce=async e=>{let t=re(e);if(!t)return;if(J.delete(e),Q.delete(e),await De(t))return S(e);let n=S(e);if(bt(e)&&!Se.has(e)&&n&&await K(n))return n;let r=new Promise(a=>{var s;((s=ee[e])!=null?s:ee[e]=[]).push(a)});return(A==null?void 0:A.app_id)===e?A.forced=!0:(W[e]=0,xe(e,{front:!0}),A&&!A.forced?A.handle.cancel():Y(e)),r};var _=require("react/jsx-runtime"),Fe=e=>(e!=null?e:"").replace(/\?[^#]*/,""),Ft=0,hn=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},An=u.default.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:a,web_at_top:s,splash:c,bridge:l,opaque_background:o,onWebLoadEnd:g})=>{var je,qe;let h=(0,u.useRef)(null),v=(0,u.useRef)(!1),m=H(F,p=>p.instances[e]),d=m==null?void 0:m.app.app_id,L=m==null?void 0:m.app.manifest_url,b=m==null?void 0:m.context,R=m==null?void 0:m.url_params,[i,M]=(0,u.useState)(()=>d?S(d):null),[U,j]=(0,u.useState)(!1),[Vt,Je]=(0,u.useState)(0),[Ht,oe]=(0,u.useState)(0),[Wt,O]=(0,u.useState)(!1),V=(0,u.useRef)(null),Ue=p=>{V.current&&clearTimeout(V.current),V.current=setTimeout(()=>{V.current=null,O(!0)},p)};(0,u.useEffect)(()=>()=>{V.current&&clearTimeout(V.current)},[]),(0,u.useEffect)(()=>{if(!d||!t&&i)return;let p=!0;return j(!1),(async()=>{let f=S(d),C=f?await K(f):!1;if(!p||(M(C?$=>!$||$.version!==f.version||$.permissions.join(",")!==f.permissions.join(",")?f:$:null),__DEV__&&Date.now()-Ft>1e4&&(Ft=Date.now(),await Ee()),!p))return;let q=await ce(d),G=q!==void 0?q:L?await mt(d,L):S(d);if(p){if(!G){j(!0);return}M($=>$!=null?$:G)}})(),()=>{p=!1}},[t,d,L,Vt]),(0,u.useEffect)(()=>Mt(e,p=>h.current?(h.current.postMessage(p),!0):!1),[e]);let jt=H(y,p=>{let f=d?p.downloads[d]:void 0;return(f==null?void 0:f.status)==="installed"?f.version:void 0});(0,u.useEffect)(()=>{if(t||!d||!i)return;let p=S(d);if(!p||p.version===i.version)return;let f=!0;return K(p).then(C=>{!f||!C||(N(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",i.version,"\u2192",p.version),M(p))}),()=>{f=!1}},[t,d,jt,i==null?void 0:i.version]);let Ve=H(y,p=>{var f;return d&&(f=p.apply_ticks[d])!=null?f:0});(0,u.useEffect)(()=>{if(!Ve||!d)return;let p=S(d);if(!p||p.version===(i==null?void 0:i.version))return;let f=!0;return K(p).then(C=>{!f||!C||(N(`webview:${e}`,"c\u1EADp nh\u1EADt",i==null?void 0:i.version,"\u2192",p.version),O(!1),M(p))}),()=>{f=!1}},[Ve]),(0,u.useEffect)(()=>{var C;let p=(C=E().keep_alive)==null?void 0:C.idle_close_ms;if(t||!p||p<=0)return;let f=setTimeout(()=>{we(e)},p);return()=>clearTimeout(f)},[t,e]),(0,u.useEffect)(()=>{a>0&&(j(!1),O(!1),oe(p=>p+1),Je(p=>p+1))},[a]);let He=(0,u.useRef)(t);(0,u.useEffect)(()=>{var p;He.current!==t&&(He.current=t,v.current&&((p=h.current)==null||p.injectJavaScript(st(t?"resumed":"paused"))))},[t]);let le=`${(je=i==null?void 0:i.version)!=null?je:"none"}:${(qe=i==null?void 0:i.permissions.join(","))!=null?qe:""}:${Ht}`,ie=(0,u.useMemo)(()=>JSON.stringify([b!=null?b:{},R!=null?R:{}]),[b,R]),Te=(0,u.useMemo)(()=>{var p;return ut(R!=null?R:{},(p=i==null?void 0:i.permissions)!=null?p:[])},[ie,i==null?void 0:i.permissions]),qt=(0,u.useMemo)(()=>ct(b!=null?b:{},Te)+it()+(E().debug?ot():""),[Te]),ue=(0,u.useRef)(null),We=(0,u.useRef)(null);(0,u.useEffect)(()=>{var f,C,q;if(!i)return;if(We.current!==le){We.current=le,ue.current=ie;return}if(ue.current===ie)return;let p=((C=JSON.parse((f=ue.current)!=null?f:"[]")[0])!=null?C:{}).org_id;if(ue.current=ie,p===(b==null?void 0:b.org_id)&&v.current){O(!1),Ue(1500),(q=h.current)==null||q.injectJavaScript(at(b!=null?b:{},Te));return}O(!1),oe(G=>G+1)},[ie,i,le]);let Kt=(0,u.useCallback)(async p=>{var C,q,G,$,Re;let f=tt(p.nativeEvent.data);if(!f){if(d&&(l!=null&&l.onWebEvent))try{Promise.resolve(l.onWebEvent(p.nativeEvent.data,{app_id:d,instance_id:e})).catch(x=>{console.warn("[miniapp] onWebEvent l\u1ED7i",d,x)})}catch(x){console.warn("[miniapp] onWebEvent l\u1ED7i",d,x)}return}if(f.method==="log"){let{level:x,text:I}=f;N(`web:${e}`,x!=null?x:"log",I!=null?I:"");return}if(f.method==="pong"){V.current||O(!0);return}if(f.method==="touchAtTop"){s.emit(!!f.at_top);return}if(f.method==="contextApplied"){V.current&&clearTimeout(V.current),V.current=null,O(!0);return}if(f.method==="ready"){v.current=!0,O(!0);let x=(C=F.getState().instances[e])==null?void 0:C.context;x&&((q=h.current)==null||q.injectJavaScript(ke(x)));return}try{let x=await dt(f,{getHostData:()=>{var I,X;return(X=(I=F.getState().instances[e])==null?void 0:I.host_data)!=null?X:{}},getPermissions:()=>{var I,X;return d?(X=(I=S(d))==null?void 0:I.permissions)!=null?X:[]:[]},is_dark:r,close:ne,app_id:d!=null?d:"",instance_id:e,options:l});f.id&&((G=h.current)==null||G.injectJavaScript(nt(f.id,x)))}catch(x){if(!f.id)return;let I=x==null?void 0:x.code,X=x instanceof T?x:new T(typeof I=="string"?I:"HOST_ERROR",String(($=x==null?void 0:x.message)!=null?$:x));(Re=h.current)==null||Re.injectJavaScript(rt(f.id,X))}},[e,r,d,s,l]),zt=(0,u.useCallback)(()=>{j(!1),oe(p=>p+1),Je(p=>p+1)},[]);return(0,_.jsxs)(w.View,{style:[w.StyleSheet.absoluteFill,o&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&D.behind],pointerEvents:t?"auto":"none",children:[i?(0,_.jsx)(Jt.default,{ref:h,source:{uri:i.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${i.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:qt,onMessage:Kt,bounces:!1,overScrollMode:"never",onLoadStart:p=>{N(`webview:${e}`,"load start",Fe(p.nativeEvent.url)),v.current=!1,O(!1)},onError:p=>{N(`webview:${e}`,"load error",Fe(p.nativeEvent.url),p.nativeEvent.description),j(!0),O(!1)},onLoadEnd:p=>{let f=p.nativeEvent.url;N(`webview:${e}`,"load end",Fe(f)),d&&(g==null||g({app_id:d,instance_id:e,url:f})),Ue(1500)},onContentProcessDidTerminate:()=>{v.current=!1,O(!1),oe(p=>p+1)},onRenderProcessGone:()=>(v.current=!1,O(!1),oe(p=>p+1),!0),style:D.webview},le):null,m&&(0,_.jsx)(Mn,{visible:!i||!Wt,interactive:U,children:(0,_.jsx)(mn,{splash:c,app:m.app,is_dark:r,error:U,has_bundle:!!i,retry:zt})})]})}),mn=u.default.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:a,retry:s})=>{let c=e,l=be(t.app_id),o=r?"error":!a&&(l==null?void 0:l.status)==="downloading"?"downloading":"loading";return(0,_.jsx)(c,{app:t,is_dark:n,status:o,progress:o==="downloading"?l==null?void 0:l.progress:void 0,retry:s})}),Mn=({visible:e,interactive:t,children:n})=>{let r=(0,u.useRef)(new w.Animated.Value(e?1:0)).current,[a,s]=(0,u.useState)(e);return(0,u.useEffect)(()=>{if(e){s(!0),r.setValue(1);return}let c=w.Animated.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return c.start(({finished:l})=>{l&&s(!1)}),()=>c.stop()},[e,r]),a?(0,_.jsx)(w.Animated.View,{style:[w.StyleSheet.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},Be=({app:e,is_dark:t,status:n,progress:r,retry:a})=>{let s=t?"#FAFAFA":"#18181B";return(0,_.jsxs)(w.View,{style:[D.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[(0,_.jsx)(w.View,{style:[D.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?(0,_.jsx)(w.Image,{source:{uri:e.icon},style:D.splash_icon_image}):(0,_.jsx)(w.Text,{style:D.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),(0,_.jsx)(w.Text,{style:[D.splash_name,{color:s}],children:e.name}),n==="error"?(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(w.Text,{style:D.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),(0,_.jsx)(w.TouchableOpacity,{activeOpacity:.7,style:[D.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:a,children:(0,_.jsx)(w.Text,{style:[D.retry_text,{color:s}],children:"Th\u1EED l\u1EA1i"})})]}):(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(w.ActivityIndicator,{style:D.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&(0,_.jsxs)(w.Text,{style:D.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},Bt=(e,t)=>{let n=(0,u.useRef)(t),r=(0,u.useRef)(!1);__DEV__&&!r.current&&n.current!==t&&(r.current=!0,console.warn(`[miniapp] MiniAppHost prop "${e}" \u0111\u1ED5i gi\u1EEFa c\xE1c l\u1EA7n render \u2192 m\u1ECDi WebView b\u1ECB mount l\u1EA1i. Khai b\xE1o component b\xEAn ngo\xE0i render.`))},yn=({container:e,splash:t=Be,is_dark:n=!1,bridge:r,close_on_back:a=!0,opaque_background:s=!0,onWebLoadEnd:c})=>{Bt("container",e),Bt("splash",t);let l=e,o=H(F,i=>i.active_key),g=(0,u.useRef)(o);o&&(g.current=o);let h=H(F,i=>Object.keys(i.instances).join("|")),v=H(F,i=>{var M;return i.active_key?(M=i.instances[i.active_key])==null?void 0:M.app.name:void 0}),m=(0,u.useMemo)(()=>h?h.split("|"):[],[h]),[d,L]=(0,u.useState)({}),b=(0,u.useRef)(hn()).current;(0,u.useEffect)(()=>{if(!o||!a)return;let i=w.BackHandler.addEventListener("hardwareBackPress",()=>(ne(),!0));return()=>i.remove()},[o,a]);let R=(0,u.useCallback)(()=>{let i=F.getState().active_key;i&&L(M=>({...M,[i]:(M[i]||0)+1}))},[]);return m.length?(0,_.jsx)(l,{visible:!!o,title:v!=null?v:"",is_dark:n,close:ne,reload:R,subscribeWebAtTop:b.subscribe,children:m.map(i=>(0,_.jsx)(An,{instance_key:i,is_active:o===i,is_front:(o!=null?o:g.current)===i,is_dark:n,reload_tick:d[i]||0,web_at_top:b,splash:t,bridge:r,opaque_background:s,onWebLoadEnd:c},i))}):null},D=w.StyleSheet.create({webview:{flex:1,backgroundColor:"transparent"},behind:{zIndex:-1},splash:{flex:1,alignItems:"center",justifyContent:"center",gap:12},splash_icon:{width:72,height:72,borderRadius:20,alignItems:"center",justifyContent:"center",overflow:"hidden"},splash_icon_image:{width:72,height:72},splash_letter:{fontSize:28,fontWeight:"700",color:"#1D4ED8"},splash_name:{fontSize:16,fontWeight:"600"},splash_hint:{color:"#71717A"},splash_spinner:{marginTop:8},retry_button:{marginTop:4,paddingHorizontal:20,paddingVertical:10,borderRadius:999},retry_text:{fontWeight:"600"}}),Ut=u.default.memo(yn);0&&(module.exports={DefaultMiniAppSplash,MINIAPP_PLATFORM_URL,MiniAppHost,MiniAppHostError,closeMiniApp,configureMiniApp,createMmkvStorage,createRnfsFileSystem,ensureMiniApp,getLocalMiniApp,getMiniAppCatalog,getMiniAppCatalogEntry,getMiniAppStatuses,getMiniAppUpdate,onMiniAppEvent,openMiniApp,pauseMiniApp,pauseMiniAppDownloads,preloadMiniApp,restoreMiniApp,resumeMiniApp,resumeMiniAppDownloads,sendEventToWeb,syncMiniAppCatalog,uninstallMiniApp,updateMiniApp,useMiniAppDownload,useMiniAppDownloadsPaused});
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var xe="https://retion-miniapp-platform.vercel.app",Q=null,Ye=new Set,Ot=e=>{Q=e,Ye.forEach(t=>t())},S=()=>{if(!Q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return Q},Qe=e=>{Ye.add(e),Q&&e()},B=(...e)=>{Q!=null&&Q.debug&&console.log("[miniapp]",...e)};var kt=(e,t)=>({document_dir:e.DocumentDirectoryPath,cache_dir:e.CachesDirectoryPath,exists:n=>e.exists(n),mkdir:n=>e.mkdir(n),remove:n=>e.unlink(n).catch(()=>{}),listDir:n=>e.readDir(n).then(r=>r.map(a=>a.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:a})=>{let{jobId:o,promise:l}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:s,contentLength:p})=>a==null?void 0:a(s,p)});return{promise:l.then(({statusCode:s})=>({status:s})),cancel:()=>e.stopDownload(o)}}}),It=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});import Ve,{useCallback as Be,useEffect as V,useMemo as Se,useRef as N,useState as Z}from"react";import{ActivityIndicator as cn,Animated as Ne,BackHandler as ln,Image as un,StyleSheet as We,Text as pe,TouchableOpacity as dn,View as Je}from"react-native";import gn from"react-native-webview";import{Linking as Dt,Platform as Lt}from"react-native";var de=1,_=class extends Error{constructor(n,r){super(r);this.code=n}},Xe=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===de&&typeof t.method=="string"?t:null}catch{return null}},ge=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,Ze=(e,t)=>ge({id:e,result:t}),et=(e,t)=>ge({id:e,error:{code:t.code,message:t.message}}),Re=e=>ge({event:"context",data:e});var tt=()=>`(function () {
1
+ var Te="https://retion-miniapp-platform.vercel.app",Z=null,Ge=new Set,Lt=e=>{Z=e,Ge.forEach(t=>t())},S=()=>{if(!Z)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return Z},Xe=e=>{Ge.add(e),Z&&e()},L=(...e)=>{Z!=null&&Z.debug&&console.log("[miniapp]",...e)};var $t=(e,t)=>({document_dir:e.DocumentDirectoryPath,cache_dir:e.CachesDirectoryPath,exists:n=>e.exists(n),mkdir:n=>e.mkdir(n),remove:n=>e.unlink(n).catch(()=>{}),listDir:n=>e.readDir(n).then(r=>r.map(a=>a.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:a})=>{let{jobId:s,promise:c}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:l,contentLength:o})=>a==null?void 0:a(l,o)});return{promise:c.then(({statusCode:l})=>({status:l})),cancel:()=>e.stopDownload(s)}}}),Nt=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});import Ve,{useCallback as Je,useEffect as B,useMemo as be,useRef as J,useState as te}from"react";import{ActivityIndicator as hn,Animated as Fe,BackHandler as An,Image as mn,StyleSheet as He,Text as le,TouchableOpacity as Mn,View as Ue}from"react-native";import yn from"react-native-webview";import{Linking as Ft,Platform as Bt}from"react-native";var fe=1,b=class extends Error{constructor(n,r){super(r);this.code=n}},et=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===fe&&typeof t.method=="string"?t:null}catch{return null}},he=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,tt=(e,t)=>he({id:e,result:t}),nt=(e,t)=>he({id:e,error:{code:t.code,message:t.message}}),Ce=e=>he({event:"context",data:e});var rt=()=>`(function () {
2
2
  var post = function (level, args) {
3
3
  try {
4
4
  var parts = [];
@@ -8,7 +8,7 @@ var xe="https://retion-miniapp-platform.vercel.app",Q=null,Ye=new Set,Ot=e=>{Q=e
8
8
  else if (typeof a === 'object') { try { parts.push(JSON.stringify(a).slice(0, 800)); } catch (e) { parts.push(String(a)); } }
9
9
  else { parts.push(String(a)); }
10
10
  }
11
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${de}, method: 'log', level: level, text: parts.join(' ') }));
11
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${fe}, method: 'log', level: level, text: parts.join(' ') }));
12
12
  } catch (e) {}
13
13
  };
14
14
  ['log', 'info', 'warn', 'error'].forEach(function (level) {
@@ -19,7 +19,7 @@ var xe="https://retion-miniapp-platform.vercel.app",Q=null,Ye=new Set,Ot=e=>{Q=e
19
19
  window.addEventListener('unhandledrejection', function (e) { post('error', ['[unhandledrejection]', e.reason]); });
20
20
  // Kh\xF4ng log query (c\xF3 th\u1EC3 ch\u1EE9a token) \u2014 ch\u1EC9 \u0111\u01B0\u1EDDng d\u1EABn + route.
21
21
  post('info', ['[page] ' + location.pathname + location.hash]);
22
- })(); true;`,nt=()=>`(function () {
22
+ })(); true;`,ot=()=>`(function () {
23
23
  function atTop(el) {
24
24
  for (var n = el; n && n !== document.documentElement; n = n.parentElement) {
25
25
  if (n.scrollTop > 0) { return false; }
@@ -30,7 +30,7 @@ var xe="https://retion-miniapp-platform.vercel.app",Q=null,Ye=new Set,Ot=e=>{Q=e
30
30
  function report(at_top) {
31
31
  if (at_top === last) { return; }
32
32
  last = at_top;
33
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${de}, method: 'touchAtTop', at_top: at_top }));
33
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${fe}, method: 'touchAtTop', at_top: at_top }));
34
34
  }
35
35
  document.addEventListener('touchstart', function (e) { report(atTop(e.target)); }, { capture: true, passive: true });
36
36
  // Cu\u1ED9n r\u1EDDi \u0111\u1EA7u trang \u2192 b\xE1o ngay, kh\xF4ng \u0111\u1EE3i l\u1EA7n ch\u1EA1m sau (tr\xE1nh host d\xF9ng gi\xE1 tr\u1ECB c\u0169 "\u0111ang \u1EDF \u0111\u1EA7u").
@@ -38,8 +38,8 @@ var xe="https://retion-miniapp-platform.vercel.app",Q=null,Ye=new Set,Ot=e=>{Q=e
38
38
  var el = e.target === document ? document.documentElement : e.target;
39
39
  if (el && el.scrollTop > 0) { report(false); }
40
40
  }, { capture: true, passive: true });
41
- })(); true;`,rt=e=>ge({event:e}),ot=(e,t)=>{let n=st(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
- ${Re(e)}`},st=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),it=(e,t={})=>{let n=st(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${de} };
41
+ })(); true;`,it=e=>he({event:e}),st=(e,t)=>{let n=at(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
+ ${Ce(e)}`},at=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),pt=(e,t={})=>{let n=at(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${fe} };
43
43
  window.__RETION_MINIAPP_CONTEXT__ = ${JSON.stringify(e)};
44
44
  ${n?`try { history.replaceState(history.state, '', location.pathname + '?' + ${JSON.stringify(n)} + location.hash); } catch (e) {}`:""}
45
- true;`},at={partner:"partner_token",chatbox:"chatbox_token"},pt=(e,t)=>{let n={...e};for(let r of Object.values(at))t.includes(r)||delete n[r];return n},Ee=new Set,Ge=async(e,t)=>{if(Ee.has(e))throw new _("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);Ee.add(e);try{return await t()}finally{Ee.delete(e)}},Te=(e,t)=>{if(typeof e!="string"||!e)throw new _("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},ct=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:a,close:o,app_id:l,instance_id:s,options:p})=>{var m,d,k,w;let g=p==null?void 0:p.handlers,h={app_id:l,instance_id:s,close:o},M=()=>new _("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let u=g==null?void 0:g.requestPayment;if(!u)throw M();let i=t==null?void 0:t.amount;if(typeof i!="number"||!Number.isFinite(i)||i<=0)throw new _("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let x={...t,amount:i,currency:Te(t==null?void 0:t.currency,"currency")};return Ge(e,()=>u(x,h))}case"printImage":{let u=g==null?void 0:g.printImage;if(!u)throw M();let i=Te(t==null?void 0:t.image,"image");await Ge(e,()=>u({image:i},h));return}case"openScreen":if(!(g!=null&&g.openScreen))throw M();await g.openScreen({screen:Te(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},h);return;case"closeApp":o();return;case"openWebview":{let u=String((m=t==null?void 0:t.url)!=null?m:"");if(!/^https?:\/\//i.test(u))throw new _("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(p!=null&&p.openUrl?p.openUrl(u):Dt.openURL(u));return}case"showToast":(k=p==null?void 0:p.showToast)==null||k.call(p,String((d=t==null?void 0:t.message)!=null?d:""));return;case"getSystemInfo":return{platform:Lt.OS==="ios"?"ios":"android",appVersion:(w=p==null?void 0:p.app_version)!=null?w:"",theme:a?"dark":"light"};case"getAccessToken":{let u=n().access_token;if(!u)throw new _("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return u}case"getToken":{let u=t==null?void 0:t.type;if(u==="access"){let q=n().access_token;if(!q)throw new _("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return q}if(u!=="partner"&&u!=="chatbox")throw new _("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(u)}`);let i=at[u];if(!r().includes(i))throw new _("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${i} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let x=u==="partner"?n().partner_token:n().chatbox_token;if(!x)throw new _("HOST_ERROR",`Kh\xF4ng c\xF3 ${i}`);return x}case"getUserInfo":{let u=n().user;if(!u)throw new _("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return u}case"getPageInfo":{let u=n().page;if(!u)throw new _("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return u}case"sendMessage":case"insertText":throw new _("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new _("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var Pe=e=>`bundle:${e}`,Ce=()=>`${S().file_system.document_dir}/miniapps`,dt=(e,t,n="index.html",r=!1,a=[])=>{let o=`${Ce()}/${e}/${t}`;return{app_id:e,version:t,dir:o,entry_uri:`file://${o}/${n}`,context_update:r,permissions:a}},lt=e=>{var t;S().storage.setString(Pe(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},$t=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,b=e=>{let t=S().storage.getString(Pe(e));if(!t)return null;try{let{version:n,entry:r,context_update:a,permissions:o}=JSON.parse(t);return dt(e,n,r,!!a,Array.isArray(o)?o:[])}catch{return null}},fe=e=>S().file_system.exists(e.entry_uri.replace("file://","")),Oe=async e=>{let t=b(e.app_id);return(t==null?void 0:t.version)===e.version&&await fe(t)},Nt=async(e,t)=>{let n=S().file_system,r=`${Ce()}/${e}`,a=await n.listDir(r).catch(()=>[]);await Promise.all(a.filter(o=>!t.includes(o)).map(o=>n.remove(`${r}/${o}`).catch(()=>{})))},gt=async e=>{var t;await((t=se[e])==null?void 0:t.catch(()=>{})),S().storage.setString(Pe(e),""),await S().file_system.remove(`${Ce()}/${e}`).catch(()=>{})},ee=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},se={},ke=(e,{base_url:t,onProgress:n}={})=>{var m;let r=S().file_system,a=null,o=!1,l=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,s=()=>{if(o)throw new ee},p=async()=>{var w;s();let d=b(e.app_id);if((d==null?void 0:d.version)===e.version&&await r.exists(d.dir))return lt(e),b(e.app_id);s();let k=r.download({url:t?$t(t,e.bundle_url):e.bundle_url,to_file:l,onProgress:(u,i)=>{var q;let x=i>0?i:(q=e.size)!=null?q:0;x>0&&(n==null||n(Math.min(1,u/x)))}});a=k;try{let{status:u}=await k.promise;if(s(),u!==200)throw new Error(`bundle ${u}`);if(e.sha256)if(r.sha256){if(await r.sha256(l)!==e.sha256)throw new Error("sha256 mismatch")}else B("b\u1ECF qua ki\u1EC3m tra sha256 (file_system kh\xF4ng c\xF3 sha256)",e.app_id);s();let i=dt(e.app_id,e.version,e.entry,!!e.context_update,(w=e.permissions)!=null?w:[]);return await r.remove(i.dir).catch(()=>{}),await r.mkdir(i.dir),await r.unzip(l,i.dir),lt(e),Nt(e.app_id,[e.version,d==null?void 0:d.version].filter(Boolean)),i}catch(u){throw o?new ee:u}finally{a=null,r.remove(l).catch(()=>{})}},h=((m=se[e.app_id])!=null?m:Promise.resolve()).catch(()=>{}).then(p),M=h.catch(()=>{});return se[e.app_id]=M,M.then(()=>{se[e.app_id]===M&&delete se[e.app_id]}),{promise:h,cancel:()=>{o=!0,a==null||a.cancel()}}},oe={},Ft=__DEV__?0:60*1e3,ut={},ft=(e,t)=>{var r,a;let n=b(e);return n&&Date.now()-((r=ut[t])!=null?r:0)<Ft?Promise.resolve(n):((a=oe[e])!=null||(oe[e]=(async()=>{let o=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!o.ok)throw new Error(`manifest ${o.status}`);let l=await o.json(),s=await ke(l,{base_url:t}).promise;return ut[t]=Date.now(),s})().catch(o=>(console.warn("[miniapp] sync failed",e,o==null?void 0:o.message),b(e))).finally(()=>{oe[e]=void 0})),oe[e])};var he=new Map,ht=(e,t)=>(he.set(e,t),()=>{he.get(e)===t&&he.delete(e)}),Bt=(e,t)=>{let n=he.get(e);return n?n(t):!1};import{useRef as Jt,useSyncExternalStore as Vt}from"react";var Ae=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let a=typeof r=="function"?r(t):r;t={...t,...a},n.forEach(o=>o())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},W=(e,t,n=Object.is)=>{let r=Jt(null),a=()=>{let o=e.getState(),l=r.current;if(l&&l.state===o&&l.selector===t)return l.value;let s=t(o),p=l&&n(l.value,s)?l.value:s;return r.current={state:o,selector:t,value:p},p};return Vt(e.subscribe,a)};var L=Ae({active_key:null,instances:{}}),At=({app:e,instance_id:t,context:n={},url_params:r={},host_data:a={}},o)=>{var s;let l=(s=S().keep_alive)==null?void 0:s.max_webviews;L.setState(p=>{let g=t!=null?t:e.app_id,h={...p.instances,[g]:{key:g,app:e,context:n,url_params:r,host_data:a,last_used_at:Date.now()}},M=Object.keys(h);return l&&l>0&&M.length>l&&M.filter(m=>m!==g).sort((m,d)=>h[m].last_used_at-h[d].last_used_at).slice(0,M.length-l).forEach(m=>{delete h[m]}),o?{active_key:g,instances:h}:{instances:h}})},Wt=e=>At(e,!0),jt=e=>At(e,!1),ie=()=>L.setState({active_key:null}),me=e=>{L.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var mt="catalog",qt="paused_apps",Ht="removed_apps",Ut=10*1e3,Kt=2,zt=3e3,Yt=()=>{var e;try{return JSON.parse((e=S().storage.getString(mt))!=null?e:"{}")}catch{return{}}},v=Ae({catalog:{},downloads:{},pause_reasons:[]}),Mt=e=>{let t=new Set,n=()=>S().storage.setString(e,JSON.stringify([...t]));return{has:r=>t.has(r),values:()=>[...t],add:r=>t.has(r)?!1:(t.add(r),n(),!0),delete:r=>t.delete(r)?(n(),!0):!1,load:()=>{var r;t.clear();try{let a=JSON.parse((r=S().storage.getString(e))!=null?r:"[]");Array.isArray(a)&&a.forEach(o=>{typeof o=="string"&&t.add(o)})}catch{}}}},$=Mt(qt),K=Mt(Ht);Qe(()=>{$.load(),K.load();let e=Yt(),t={};Object.keys(e).filter(n=>!K.has(n)).forEach(n=>{let r=b(n);r?t[n]={status:"installed",progress:1,version:r.version,has_local:!0}:$.has(n)&&(t[n]={status:"paused",progress:0,version:e[n].version,has_local:!1})}),v.setState({catalog:e,downloads:t})});var De=e=>W(v,t=>e?t.downloads[e]:void 0),Qt=()=>W(v,e=>e.pause_reasons.length>0),J=(...e)=>B("queue",...e),E=[],j={},A=null,Me=new Set,G={},Ie=new Set,X=e=>{Ie.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},Gt=e=>(Ie.add(e),()=>{Ie.delete(e)}),Xt=()=>v.getState().downloads,C=(e,t)=>{let n=!!b(e),r=v.getState().downloads[e],a=t.status==="downloading"&&n?"updating":t.status,o={...r!=null?r:{status:"queued",progress:0},...t,...a?{status:a}:{},has_local:n};v.setState(l=>({downloads:{...l.downloads,[e]:o}})),(r==null?void 0:r.status)!==o.status||(r==null?void 0:r.version)!==o.version||(r==null?void 0:r.has_local)!==o.has_local?X({type:"status_change",app_id:e,state:o}):r.progress!==o.progress&&X({type:"progress",app_id:e,progress:o.progress,version:o.version})},we=(e,t)=>{var n;(n=G[e])==null||n.forEach(r=>r(t)),delete G[e]},Zt=()=>v.getState().pause_reasons.length>0,U=e=>{var s;if(A)return;let t=e?E.indexOf(e):Zt()?-1:E.findIndex(p=>!$.has(p));if(t<0||t>=E.length)return;let[n]=E.splice(t,1),r=v.getState().catalog[n];if(!r){we(n,b(n)),U();return}let a=Date.now();j[n]=((s=j[n])!=null?s:0)+1,C(n,{status:"downloading",progress:0,version:r.version,error:void 0});let o=0,l=ke(r,{onProgress:p=>{let g=Math.floor(p*100);g!==o&&(o=g,C(n,{progress:g/100,version:r.version}))}});A={app_id:n,handle:l,forced:!!e},J("start",n,r.version,e?"(forced)":""),l.promise.then(p=>{J("installed",n,r.version,`${Date.now()-a}ms`),C(n,{status:"installed",progress:1,version:r.version}),we(n,p)}).catch(p=>{var h;if(p instanceof ee){if(Me.has(n))return;J("paused",n),j[n]-=1,E.unshift(n),C(n,{status:$.has(n)?"paused":"queued",progress:0,version:r.version});return}let g=String((h=p==null?void 0:p.message)!=null?h:p);if(console.warn("[miniapp-queue] failed",n,g),j[n]<Kt){C(n,{status:"queued",progress:0,version:r.version,error:g}),setTimeout(()=>{var M;E.includes(n)||(A==null?void 0:A.app_id)===n||(E.push(n),U((M=G[n])!=null&&M.length?n:void 0))},zt);return}C(n,{status:"failed",progress:0,version:r.version,error:g}),we(n,b(n))}).finally(()=>{A=null;let p=E.find(g=>{var h;return(h=G[g])==null?void 0:h.length});U(p)})},ye=(e,{front:t=!1}={})=>{if((A==null?void 0:A.app_id)===e)return;let n=E.indexOf(e);if(n>=0){if(!t)return;E.splice(n,1)}t?E.unshift(e):E.push(e)},en=async e=>{let{host_id:t,client_token:n}=S(),r=new AbortController,a=setTimeout(()=>r.abort(),Ut);try{let o=`${xe}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,l=await fetch(o,{headers:{Authorization:`Bearer ${n}`,"Cache-Control":"no-cache"},signal:r.signal});if(!l.ok)throw new Error(`host list ${e} ${l.status}`);return(await l.json()).apps.map(p=>({...p,channel:e}))}finally{clearTimeout(a)}},ae=null,Le=()=>(ae!=null||(ae=(async()=>{var t;let e=Date.now();try{let n=await Promise.all(S().channels.map(en)),r={};[...n].reverse().flat().forEach(s=>{r[s.app_id]=s});let a=Object.keys(v.getState().catalog).filter(s=>!r[s]);S().storage.setString(mt,JSON.stringify(r)),v.setState({catalog:r}),await Promise.all(a.map(s=>wt(s,{by_user:!1}))),a.forEach(s=>K.delete(s));let o=Object.keys(r).filter(s=>!K.has(s)),l=[];for(let s of o.map(p=>r[p]))await Oe(s)?C(s.app_id,{status:"installed",progress:1,version:s.version}):l.push(s);return l.forEach(s=>{j[s.app_id]=0,C(s.app_id,{status:$.has(s.app_id)?"paused":"queued",progress:0,version:s.version,error:void 0}),ye(s.app_id)}),J("catalog",o.length,"apps, outdated",l.map(s=>s.app_id),"removed",a,`${Date.now()-e}ms`),X({type:"sync_complete",app_ids:o,removed:a}),U(),{ok:!0,app_ids:o,removed:a}}catch(n){let r=String((n==null?void 0:n.name)==="AbortError"?"timeout":(t=n==null?void 0:n.message)!=null?t:n);return console.warn("[miniapp-queue] sync catalog failed",r),X({type:"sync_failed",error:r}),{ok:!1,error:r}}finally{ae=null}})()),ae),wt=async(e,{by_user:t})=>{var a,o,l,s;if(t&&K.add(e),Me.has(e))return;Me.add(e),$.delete(e);let n=E.indexOf(e);n>=0&&E.splice(n,1),(A==null?void 0:A.app_id)===e&&A.handle.cancel();let r=(s=(l=(a=v.getState().downloads[e])==null?void 0:a.version)!=null?l:(o=b(e))==null?void 0:o.version)!=null?s:"";C(e,{status:"uninstalling",progress:0,version:r}),await gt(e),me(e),v.setState(p=>{let g={...p.downloads};return delete g[e],{downloads:g}}),delete j[e],Me.delete(e),we(e,null),J("uninstalled",e,t?"(user)":"(not in list)"),X({type:"uninstalled",app_id:e})},tn=e=>wt(e,{by_user:!0}),nn=e=>{let t=ve(e);return t?(K.delete(e),(A==null?void 0:A.app_id)===e||E.includes(e)||(j[e]=0,C(e,{status:$.has(e)?"paused":"queued",progress:0,version:t.version,error:void 0}),ye(e),U(),J("restore",e)),!0):!1},rn=e=>{if($.has(e))return;if($.add(e),J("pause app",e),(A==null?void 0:A.app_id)===e&&!A.forced){A.handle.cancel();return}let t=v.getState().downloads[e];E.includes(e)&&t&&C(e,{status:"paused",progress:0,version:t.version})},on=e=>{if(!$.delete(e))return;J("resume app",e);let t=v.getState().downloads[e];(t==null?void 0:t.status)==="paused"&&!E.includes(e)&&ve(e)&&(j[e]=0,ye(e)),E.includes(e)&&t&&C(e,{status:"queued",progress:0,version:t.version}),U()},sn=e=>{let{pause_reasons:t}=v.getState();t.includes(e)||(v.setState({pause_reasons:[...t,e]}),J("pause",e),t.length===0&&X({type:"pause_change",paused:!0,reasons:[e]}),A&&!A.forced&&A.handle.cancel())},an=e=>{let{pause_reasons:t}=v.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);v.setState({pause_reasons:n}),J("resume",e),n.length===0&&X({type:"pause_change",paused:!1,reasons:n}),U()},pn=()=>Object.values(v.getState().catalog).map(e=>({...e,installed:!!b(e.app_id),removed_by_user:K.has(e.app_id)})),ve=e=>v.getState().catalog[e],$e=async e=>{let t=ve(e);if(!t)return;if($.delete(e),K.delete(e),await Oe(t))return b(e);let n=new Promise(r=>{var a;((a=G[e])!=null?a:G[e]=[]).push(r)});return(A==null?void 0:A.app_id)===e?A.forced=!0:(j[e]=0,ye(e,{front:!0}),A&&!A.forced?A.handle.cancel():U(e)),n};import{Fragment as St,jsx as T,jsxs as ce}from"react/jsx-runtime";var Fe=e=>(e!=null?e:"").replace(/\?[^#]*/,""),yt=0,fn=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},hn=Ve.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:a,web_at_top:o,splash:l,bridge:s,opaque_background:p,onWebLoadEnd:g})=>{var Ke,ze;let h=N(null),M=N(!1),m=W(L,c=>c.instances[e]),d=m==null?void 0:m.app.app_id,k=m==null?void 0:m.app.manifest_url,w=m==null?void 0:m.context,u=m==null?void 0:m.url_params,[i,x]=Z(()=>d?b(d):null),[q,te]=Z(!1),[bt,je]=Z(0),[xt,ne]=Z(0),[Et,I]=Z(!1),F=N(null),qe=c=>{F.current&&clearTimeout(F.current),F.current=setTimeout(()=>{F.current=null,I(!0)},c)};V(()=>()=>{F.current&&clearTimeout(F.current)},[]),V(()=>{if(!d||!t&&i)return;let c=!0;return te(!1),(async()=>{let f=b(d),R=f?await fe(f):!1;if(!c||(x(R?D=>!D||D.version!==f.version||D.permissions.join(",")!==f.permissions.join(",")?f:D:null),__DEV__&&Date.now()-yt>1e4&&(yt=Date.now(),await Le()),!c))return;let H=await $e(d),z=H!==void 0?H:k?await ft(d,k):b(d);if(c){if(!z){te(!0);return}x(D=>D!=null?D:z)}})(),()=>{c=!1}},[t,d,k,bt]),V(()=>ht(e,c=>h.current?(h.current.postMessage(c),!0):!1),[e]);let Tt=W(v,c=>{let f=d?c.downloads[d]:void 0;return(f==null?void 0:f.status)==="installed"?f.version:void 0});V(()=>{if(t||!d||!i)return;let c=b(d);if(!c||c.version===i.version)return;let f=!0;return fe(c).then(R=>{!f||!R||(B(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",i.version,"\u2192",c.version),x(c))}),()=>{f=!1}},[t,d,Tt,i==null?void 0:i.version]),V(()=>{var R;let c=(R=S().keep_alive)==null?void 0:R.idle_close_ms;if(t||!c||c<=0)return;let f=setTimeout(()=>{me(e)},c);return()=>clearTimeout(f)},[t,e]),V(()=>{a>0&&(te(!1),I(!1),ne(c=>c+1),je(c=>c+1))},[a]);let He=N(t);V(()=>{var c;He.current!==t&&(He.current=t,M.current&&((c=h.current)==null||c.injectJavaScript(rt(t?"resumed":"paused"))))},[t]);let le=`${(Ke=i==null?void 0:i.version)!=null?Ke:"none"}:${(ze=i==null?void 0:i.permissions.join(","))!=null?ze:""}:${xt}`,re=Se(()=>JSON.stringify([w!=null?w:{},u!=null?u:{}]),[w,u]),_e=Se(()=>{var c;return pt(u!=null?u:{},(c=i==null?void 0:i.permissions)!=null?c:[])},[re,i==null?void 0:i.permissions]),Rt=Se(()=>it(w!=null?w:{},_e)+nt()+(S().debug?tt():""),[_e]),ue=N(null),Ue=N(null);V(()=>{var f,R,H;if(!i)return;if(Ue.current!==le){Ue.current=le,ue.current=re;return}if(ue.current===re)return;let c=((R=JSON.parse((f=ue.current)!=null?f:"[]")[0])!=null?R:{}).org_id;if(ue.current=re,c===(w==null?void 0:w.org_id)&&M.current){I(!1),qe(1500),(H=h.current)==null||H.injectJavaScript(ot(w!=null?w:{},_e));return}I(!1),ne(z=>z+1)},[re,i,le]);let Pt=Be(async c=>{var R,H,z,D,be;let f=Xe(c.nativeEvent.data);if(!f){if(d&&(s!=null&&s.onWebEvent))try{Promise.resolve(s.onWebEvent(c.nativeEvent.data,{app_id:d,instance_id:e})).catch(y=>{console.warn("[miniapp] onWebEvent l\u1ED7i",d,y)})}catch(y){console.warn("[miniapp] onWebEvent l\u1ED7i",d,y)}return}if(f.method==="log"){let{level:y,text:P}=f;B(`web:${e}`,y!=null?y:"log",P!=null?P:"");return}if(f.method==="pong"){F.current||I(!0);return}if(f.method==="touchAtTop"){o.emit(!!f.at_top);return}if(f.method==="contextApplied"){F.current&&clearTimeout(F.current),F.current=null,I(!0);return}if(f.method==="ready"){M.current=!0,I(!0);let y=(R=L.getState().instances[e])==null?void 0:R.context;y&&((H=h.current)==null||H.injectJavaScript(Re(y)));return}try{let y=await ct(f,{getHostData:()=>{var P,Y;return(Y=(P=L.getState().instances[e])==null?void 0:P.host_data)!=null?Y:{}},getPermissions:()=>{var P,Y;return d?(Y=(P=b(d))==null?void 0:P.permissions)!=null?Y:[]:[]},is_dark:r,close:ie,app_id:d!=null?d:"",instance_id:e,options:s});f.id&&((z=h.current)==null||z.injectJavaScript(Ze(f.id,y)))}catch(y){if(!f.id)return;let P=y==null?void 0:y.code,Y=y instanceof _?y:new _(typeof P=="string"?P:"HOST_ERROR",String((D=y==null?void 0:y.message)!=null?D:y));(be=h.current)==null||be.injectJavaScript(et(f.id,Y))}},[e,r,d,o,s]),Ct=Be(()=>{te(!1),ne(c=>c+1),je(c=>c+1)},[]);return ce(Je,{style:[We.absoluteFill,p&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&O.behind],pointerEvents:t?"auto":"none",children:[i?T(gn,{ref:h,source:{uri:i.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${i.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:Rt,onMessage:Pt,bounces:!1,overScrollMode:"never",onLoadStart:c=>{B(`webview:${e}`,"load start",Fe(c.nativeEvent.url)),M.current=!1,I(!1)},onError:c=>{B(`webview:${e}`,"load error",Fe(c.nativeEvent.url),c.nativeEvent.description),te(!0),I(!1)},onLoadEnd:c=>{let f=c.nativeEvent.url;B(`webview:${e}`,"load end",Fe(f)),d&&(g==null||g({app_id:d,instance_id:e,url:f})),qe(1500)},onContentProcessDidTerminate:()=>{M.current=!1,I(!1),ne(c=>c+1)},onRenderProcessGone:()=>(M.current=!1,I(!1),ne(c=>c+1),!0),style:O.webview},le):null,m&&T(mn,{visible:!i||!Et,interactive:q,children:T(An,{splash:l,app:m.app,is_dark:r,error:q,has_bundle:!!i,retry:Ct})})]})}),An=Ve.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:a,retry:o})=>{let l=e,s=De(t.app_id),p=r?"error":!a&&(s==null?void 0:s.status)==="downloading"?"downloading":"loading";return T(l,{app:t,is_dark:n,status:p,progress:p==="downloading"?s==null?void 0:s.progress:void 0,retry:o})}),mn=({visible:e,interactive:t,children:n})=>{let r=N(new Ne.Value(e?1:0)).current,[a,o]=Z(e);return V(()=>{if(e){o(!0),r.setValue(1);return}let l=Ne.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return l.start(({finished:s})=>{s&&o(!1)}),()=>l.stop()},[e,r]),a?T(Ne.View,{style:[We.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},_t=({app:e,is_dark:t,status:n,progress:r,retry:a})=>{let o=t?"#FAFAFA":"#18181B";return ce(Je,{style:[O.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[T(Je,{style:[O.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?T(un,{source:{uri:e.icon},style:O.splash_icon_image}):T(pe,{style:O.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),T(pe,{style:[O.splash_name,{color:o}],children:e.name}),n==="error"?ce(St,{children:[T(pe,{style:O.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),T(dn,{activeOpacity:.7,style:[O.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:a,children:T(pe,{style:[O.retry_text,{color:o}],children:"Th\u1EED l\u1EA1i"})})]}):ce(St,{children:[T(cn,{style:O.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&ce(pe,{style:O.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},vt=(e,t)=>{let n=N(t),r=N(!1);__DEV__&&!r.current&&n.current!==t&&(r.current=!0,console.warn(`[miniapp] MiniAppHost prop "${e}" \u0111\u1ED5i gi\u1EEFa c\xE1c l\u1EA7n render \u2192 m\u1ECDi WebView b\u1ECB mount l\u1EA1i. Khai b\xE1o component b\xEAn ngo\xE0i render.`))},Mn=({container:e,splash:t=_t,is_dark:n=!1,bridge:r,close_on_back:a=!0,opaque_background:o=!0,onWebLoadEnd:l})=>{vt("container",e),vt("splash",t);let s=e,p=W(L,i=>i.active_key),g=N(p);p&&(g.current=p);let h=W(L,i=>Object.keys(i.instances).join("|")),M=W(L,i=>{var x;return i.active_key?(x=i.instances[i.active_key])==null?void 0:x.app.name:void 0}),m=Se(()=>h?h.split("|"):[],[h]),[d,k]=Z({}),w=N(fn()).current;V(()=>{if(!p||!a)return;let i=ln.addEventListener("hardwareBackPress",()=>(ie(),!0));return()=>i.remove()},[p,a]);let u=Be(()=>{let i=L.getState().active_key;i&&k(x=>({...x,[i]:(x[i]||0)+1}))},[]);return m.length?T(s,{visible:!!p,title:M!=null?M:"",is_dark:n,close:ie,reload:u,subscribeWebAtTop:w.subscribe,children:m.map(i=>T(hn,{instance_key:i,is_active:p===i,is_front:(p!=null?p:g.current)===i,is_dark:n,reload_tick:d[i]||0,web_at_top:w,splash:t,bridge:r,opaque_background:o,onWebLoadEnd:l},i))}):null},O=We.create({webview:{flex:1,backgroundColor:"transparent"},behind:{zIndex:-1},splash:{flex:1,alignItems:"center",justifyContent:"center",gap:12},splash_icon:{width:72,height:72,borderRadius:20,alignItems:"center",justifyContent:"center",overflow:"hidden"},splash_icon_image:{width:72,height:72},splash_letter:{fontSize:28,fontWeight:"700",color:"#1D4ED8"},splash_name:{fontSize:16,fontWeight:"600"},splash_hint:{color:"#71717A"},splash_spinner:{marginTop:8},retry_button:{marginTop:4,paddingHorizontal:20,paddingVertical:10,borderRadius:999},retry_text:{fontWeight:"600"}}),wn=Ve.memo(Mn);export{_t as DefaultMiniAppSplash,xe as MINIAPP_PLATFORM_URL,wn as MiniAppHost,_ as MiniAppHostError,ie as closeMiniApp,Ot as configureMiniApp,It as createMmkvStorage,kt as createRnfsFileSystem,$e as ensureMiniApp,b as getLocalMiniApp,pn as getMiniAppCatalog,ve as getMiniAppCatalogEntry,Xt as getMiniAppStatuses,Gt as onMiniAppEvent,Wt as openMiniApp,rn as pauseMiniApp,sn as pauseMiniAppDownloads,jt as preloadMiniApp,nn as restoreMiniApp,on as resumeMiniApp,an as resumeMiniAppDownloads,Bt as sendEventToWeb,Le as syncMiniAppCatalog,tn as uninstallMiniApp,De as useMiniAppDownload,Qt as useMiniAppDownloadsPaused};
45
+ true;`},ct={partner:"partner_token",chatbox:"chatbox_token"},lt=(e,t)=>{let n={...e};for(let r of Object.values(ct))t.includes(r)||delete n[r];return n},Re=new Set,Ze=async(e,t)=>{if(Re.has(e))throw new b("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);Re.add(e);try{return await t()}finally{Re.delete(e)}},Jt=new Set(["selection","impactLight","impactMedium","impactHeavy","rigid","soft","notificationSuccess","notificationWarning","notificationError"]),Pe=(e,t)=>{if(typeof e!="string"||!e)throw new b("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},ut=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:a,close:s,app_id:c,instance_id:l,options:o})=>{var A,u,I,v,x;let d=o==null?void 0:o.handlers,f={app_id:c,instance_id:l,close:s},y=()=>new b("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let i=d==null?void 0:d.requestPayment;if(!i)throw y();let m=t==null?void 0:t.amount;if(typeof m!="number"||!Number.isFinite(m)||m<=0)throw new b("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let U={...t,amount:m,currency:Pe(t==null?void 0:t.currency,"currency")};return Ze(e,()=>i(U,f))}case"printImage":{let i=d==null?void 0:d.printImage;if(!i)throw y();let m=Pe(t==null?void 0:t.image,"image");await Ze(e,()=>i({image:m},f));return}case"openScreen":if(!(d!=null&&d.openScreen))throw y();await d.openScreen({screen:Pe(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},f);return;case"closeApp":s();return;case"openWebview":{let i=String((A=t==null?void 0:t.url)!=null?A:"");if(!/^https?:\/\//i.test(i))throw new b("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(o!=null&&o.openUrl?o.openUrl(i):Ft.openURL(i));return}case"showToast":(I=o==null?void 0:o.showToast)==null||I.call(o,String((u=t==null?void 0:t.message)!=null?u:""));return;case"haptic":{let i=Jt.has(t==null?void 0:t.type)?t.type:"selection";(v=o==null?void 0:o.haptic)==null||v.call(o,i);return}case"getSystemInfo":return{platform:Bt.OS==="ios"?"ios":"android",appVersion:(x=o==null?void 0:o.app_version)!=null?x:"",theme:a?"dark":"light"};case"getAccessToken":{let i=n().access_token;if(!i)throw new b("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return i}case"getToken":{let i=t==null?void 0:t.type;if(i==="access"){let j=n().access_token;if(!j)throw new b("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return j}if(i!=="partner"&&i!=="chatbox")throw new b("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(i)}`);let m=ct[i];if(!r().includes(m))throw new b("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${m} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let U=i==="partner"?n().partner_token:n().chatbox_token;if(!U)throw new b("HOST_ERROR",`Kh\xF4ng c\xF3 ${m}`);return U}case"getUserInfo":{let i=n().user;if(!i)throw new b("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return i}case"getPageInfo":{let i=n().page;if(!i)throw new b("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return i}case"sendMessage":case"insertText":throw new b("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new b("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var ke=e=>`bundle:${e}`,Oe=()=>`${S().file_system.document_dir}/miniapps`,ft=(e,t,n="index.html",r=!1,a=[])=>{let s=`${Oe()}/${e}/${t}`;return{app_id:e,version:t,dir:s,entry_uri:`file://${s}/${n}`,context_update:r,permissions:a}},dt=e=>{var t;S().storage.setString(ke(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},Ut=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,w=e=>{let t=S().storage.getString(ke(e));if(!t)return null;try{let{version:n,entry:r,context_update:a,permissions:s}=JSON.parse(t);return ft(e,n,r,!!a,Array.isArray(s)?s:[])}catch{return null}},K=e=>S().file_system.exists(e.entry_uri.replace("file://","")),Ie=async e=>{let t=w(e.app_id);return(t==null?void 0:t.version)===e.version&&await K(t)},Vt=async(e,t)=>{let n=S().file_system,r=`${Oe()}/${e}`,a=await n.listDir(r).catch(()=>[]);await Promise.all(a.filter(s=>!t.includes(s)).map(s=>n.remove(`${r}/${s}`).catch(()=>{})))},ht=async e=>{var t;await((t=se[e])==null?void 0:t.catch(()=>{})),S().storage.setString(ke(e),""),await S().file_system.remove(`${Oe()}/${e}`).catch(()=>{})},ne=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},se={},De=(e,{base_url:t,onProgress:n}={})=>{var A;let r=S().file_system,a=null,s=!1,c=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,l=()=>{if(s)throw new ne},o=async()=>{var v;l();let u=w(e.app_id);if((u==null?void 0:u.version)===e.version&&await r.exists(u.dir))return dt(e),w(e.app_id);l();let I=r.download({url:t?Ut(t,e.bundle_url):e.bundle_url,to_file:c,onProgress:(x,i)=>{var U;let m=i>0?i:(U=e.size)!=null?U:0;m>0&&(n==null||n(Math.min(1,x/m)))}});a=I;try{let{status:x}=await I.promise;if(l(),x!==200)throw new Error(`bundle ${x}`);if(e.sha256)if(r.sha256){if(await r.sha256(c)!==e.sha256)throw new Error("sha256 mismatch")}else L("b\u1ECF qua ki\u1EC3m tra sha256 (file_system kh\xF4ng c\xF3 sha256)",e.app_id);l();let i=ft(e.app_id,e.version,e.entry,!!e.context_update,(v=e.permissions)!=null?v:[]);return await r.remove(i.dir).catch(()=>{}),await r.mkdir(i.dir),await r.unzip(c,i.dir),dt(e),Vt(e.app_id,[e.version,u==null?void 0:u.version].filter(Boolean)),i}catch(x){throw s?new ne:x}finally{a=null,r.remove(c).catch(()=>{})}},f=((A=se[e.app_id])!=null?A:Promise.resolve()).catch(()=>{}).then(o),y=f.catch(()=>{});return se[e.app_id]=y,y.then(()=>{se[e.app_id]===y&&delete se[e.app_id]}),{promise:f,cancel:()=>{s=!0,a==null||a.cancel()}}},ie={},Ht=__DEV__?0:60*1e3,gt={},At=(e,t)=>{var r,a;let n=w(e);return n&&Date.now()-((r=gt[t])!=null?r:0)<Ht?Promise.resolve(n):((a=ie[e])!=null||(ie[e]=(async()=>{let s=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!s.ok)throw new Error(`manifest ${s.status}`);let c=await s.json(),l=await De(c,{base_url:t}).promise;return gt[t]=Date.now(),l})().catch(s=>(console.warn("[miniapp] sync failed",e,s==null?void 0:s.message),w(e))).finally(()=>{ie[e]=void 0})),ie[e])};var Ae=new Map,mt=(e,t)=>(Ae.set(e,t),()=>{Ae.get(e)===t&&Ae.delete(e)}),Wt=(e,t)=>{let n=Ae.get(e);return n?n(t):!1};import{useRef as jt,useSyncExternalStore as qt}from"react";var me=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let a=typeof r=="function"?r(t):r;t={...t,...a},n.forEach(s=>s())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},H=(e,t,n=Object.is)=>{let r=jt(null),a=()=>{let s=e.getState(),c=r.current;if(c&&c.state===s&&c.selector===t)return c.value;let l=t(s),o=c&&n(c.value,l)?c.value:l;return r.current={state:s,selector:t,value:o},o};return qt(e.subscribe,a)};var $=me({active_key:null,instances:{}}),Mt=({app:e,instance_id:t,context:n={},url_params:r={},host_data:a={}},s)=>{var l;let c=(l=S().keep_alive)==null?void 0:l.max_webviews;$.setState(o=>{let d=t!=null?t:e.app_id,f={...o.instances,[d]:{key:d,app:e,context:n,url_params:r,host_data:a,last_used_at:Date.now()}},y=Object.keys(f);return c&&c>0&&y.length>c&&y.filter(A=>A!==d).sort((A,u)=>f[A].last_used_at-f[u].last_used_at).slice(0,y.length-c).forEach(A=>{delete f[A]}),s?{active_key:d,instances:f}:{instances:f}})},Kt=e=>Mt(e,!0),zt=e=>Mt(e,!1),ae=()=>$.setState({active_key:null}),Me=e=>{$.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var yt="catalog",Yt="paused_apps",Qt="removed_apps",Gt=10*1e3,Xt=2,Zt=3e3,en=()=>{var e;try{return JSON.parse((e=S().storage.getString(yt))!=null?e:"{}")}catch{return{}}},M=me({catalog:{},downloads:{},pause_reasons:[],updates:{},apply_ticks:{}}),wt=e=>{var t;return!!((t=S().manual_update)!=null&&t.includes(e))},ve=new Set,vt=e=>{let t=new Set,n=()=>S().storage.setString(e,JSON.stringify([...t]));return{has:r=>t.has(r),values:()=>[...t],add:r=>t.has(r)?!1:(t.add(r),n(),!0),delete:r=>t.delete(r)?(n(),!0):!1,load:()=>{var r;t.clear();try{let a=JSON.parse((r=S().storage.getString(e))!=null?r:"[]");Array.isArray(a)&&a.forEach(s=>{typeof s=="string"&&t.add(s)})}catch{}}}},F=vt(Yt),Q=vt(Qt);Xe(()=>{F.load(),Q.load();let e=en(),t={};Object.keys(e).filter(n=>!Q.has(n)).forEach(n=>{let r=w(n);r?t[n]={status:"installed",progress:1,version:r.version,has_local:!0}:F.has(n)&&(t[n]={status:"paused",progress:0,version:e[n].version,has_local:!1})}),M.setState({catalog:e,downloads:t})});var $e=e=>H(M,t=>e?t.downloads[e]:void 0),tn=()=>H(M,e=>e.pause_reasons.length>0),N=(...e)=>L("queue",...e),E=[],W={},h=null,ye=new Set,ee={},Le=new Set,z=e=>{Le.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},nn=e=>(Le.add(e),()=>{Le.delete(e)}),rn=()=>M.getState().downloads,P=(e,t)=>{let n=!!w(e),r=M.getState().downloads[e],a=t.status==="downloading"&&n?"updating":t.status,s={...r!=null?r:{status:"queued",progress:0},...t,...a?{status:a}:{},has_local:n};M.setState(c=>({downloads:{...c.downloads,[e]:s}})),(r==null?void 0:r.status)!==s.status||(r==null?void 0:r.version)!==s.version||(r==null?void 0:r.has_local)!==s.has_local?z({type:"status_change",app_id:e,state:s}):r.progress!==s.progress&&z({type:"progress",app_id:e,progress:s.progress,version:s.version})},we=(e,t)=>{var n;(n=ee[e])==null||n.forEach(r=>r(t)),delete ee[e]},on=()=>M.getState().pause_reasons.length>0,Y=e=>{var l;if(h)return;let t=e?E.indexOf(e):on()?-1:E.findIndex(o=>!F.has(o));if(t<0||t>=E.length)return;let[n]=E.splice(t,1),r=M.getState().catalog[n];if(!r){we(n,w(n)),Y();return}let a=Date.now();W[n]=((l=W[n])!=null?l:0)+1,P(n,{status:"downloading",progress:0,version:r.version,error:void 0});let s=0,c=De(r,{onProgress:o=>{let d=Math.floor(o*100);d!==s&&(s=d,P(n,{progress:d/100,version:r.version}))}});h={app_id:n,handle:c,forced:!!e},N("start",n,r.version,e?"(forced)":""),c.promise.then(o=>{N("installed",n,r.version,`${Date.now()-a}ms`),P(n,{status:"installed",progress:1,version:r.version}),we(n,o)}).catch(o=>{var f;if(o instanceof ne){if(ye.has(n))return;N("paused",n),W[n]-=1,E.unshift(n),P(n,{status:F.has(n)?"paused":"queued",progress:0,version:r.version});return}let d=String((f=o==null?void 0:o.message)!=null?f:o);if(console.warn("[miniapp-queue] failed",n,d),W[n]<Xt){P(n,{status:"queued",progress:0,version:r.version,error:d}),setTimeout(()=>{var y;E.includes(n)||(h==null?void 0:h.app_id)===n||(E.push(n),Y((y=ee[n])!=null&&y.length?n:void 0))},Zt);return}P(n,{status:"failed",progress:0,version:r.version,error:d}),we(n,w(n))}).finally(()=>{h=null;let o=E.find(d=>{var f;return(f=ee[d])==null?void 0:f.length});Y(o)})},_e=(e,{front:t=!1}={})=>{if((h==null?void 0:h.app_id)===e)return;let n=E.indexOf(e);if(n>=0){if(!t)return;E.splice(n,1)}t?E.unshift(e):E.push(e)},sn=async e=>{let{host_id:t,client_token:n}=S(),r=new AbortController,a=setTimeout(()=>r.abort(),Gt);try{let s=`${Te}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,c=await fetch(s,{headers:{Authorization:`Bearer ${n}`,"Cache-Control":"no-cache"},signal:r.signal});if(!c.ok)throw new Error(`host list ${e} ${c.status}`);return(await c.json()).apps.map(o=>({...o,channel:e}))}finally{clearTimeout(a)}},pe=null,Ne=()=>(pe!=null||(pe=(async()=>{var t;let e=Date.now();try{let n=await Promise.all(S().channels.map(sn)),r={};[...n].reverse().flat().forEach(o=>{r[o.app_id]=o});let a=Object.keys(M.getState().catalog).filter(o=>!r[o]);S().storage.setString(yt,JSON.stringify(r)),M.setState({catalog:r}),await Promise.all(a.map(o=>_t(o,{by_user:!1}))),a.forEach(o=>Q.delete(o));let s=Object.keys(r).filter(o=>!Q.has(o)),c=[],l={};for(let o of s.map(d=>r[d])){if(await Ie(o)){P(o.app_id,{status:"installed",progress:1,version:o.version});continue}let d=w(o.app_id);if(wt(o.app_id)&&!ve.has(o.app_id)&&d&&await K(d)){P(o.app_id,{status:"installed",progress:1,version:d.version}),l[o.app_id]={app_id:o.app_id,current_version:d.version,next_version:o.version};continue}c.push(o)}return M.setState({updates:l}),c.forEach(o=>{W[o.app_id]=0,P(o.app_id,{status:F.has(o.app_id)?"paused":"queued",progress:0,version:o.version,error:void 0}),_e(o.app_id)}),N("catalog",s.length,"apps, outdated",c.map(o=>o.app_id),"removed",a,`${Date.now()-e}ms`),z({type:"sync_complete",app_ids:s,removed:a}),Object.values(l).forEach(o=>z({type:"update_available",...o})),Y(),{ok:!0,app_ids:s,removed:a}}catch(n){let r=String((n==null?void 0:n.name)==="AbortError"?"timeout":(t=n==null?void 0:n.message)!=null?t:n);return console.warn("[miniapp-queue] sync catalog failed",r),z({type:"sync_failed",error:r}),{ok:!1,error:r}}finally{pe=null}})()),pe),_t=async(e,{by_user:t})=>{var a,s,c,l;if(t&&Q.add(e),ye.has(e))return;ye.add(e),F.delete(e);let n=E.indexOf(e);n>=0&&E.splice(n,1),(h==null?void 0:h.app_id)===e&&h.handle.cancel();let r=(l=(c=(a=M.getState().downloads[e])==null?void 0:a.version)!=null?c:(s=w(e))==null?void 0:s.version)!=null?l:"";P(e,{status:"uninstalling",progress:0,version:r}),await ht(e),Me(e),M.setState(o=>{let d={...o.downloads};return delete d[e],{downloads:d}}),delete W[e],ye.delete(e),we(e,null),N("uninstalled",e,t?"(user)":"(not in list)"),z({type:"uninstalled",app_id:e})},an=e=>_t(e,{by_user:!0}),pn=e=>{let t=ce(e);return t?(Q.delete(e),(h==null?void 0:h.app_id)===e||E.includes(e)||(W[e]=0,P(e,{status:F.has(e)?"paused":"queued",progress:0,version:t.version,error:void 0}),_e(e),Y(),N("restore",e)),!0):!1},cn=e=>{if(F.has(e))return;if(F.add(e),N("pause app",e),(h==null?void 0:h.app_id)===e&&!h.forced){h.handle.cancel();return}let t=M.getState().downloads[e];E.includes(e)&&t&&P(e,{status:"paused",progress:0,version:t.version})},ln=e=>{if(!F.delete(e))return;N("resume app",e);let t=M.getState().downloads[e];(t==null?void 0:t.status)==="paused"&&!E.includes(e)&&ce(e)&&(W[e]=0,_e(e)),E.includes(e)&&t&&P(e,{status:"queued",progress:0,version:t.version}),Y()},un=e=>{let{pause_reasons:t}=M.getState();t.includes(e)||(M.setState({pause_reasons:[...t,e]}),N("pause",e),t.length===0&&z({type:"pause_change",paused:!0,reasons:[e]}),h&&!h.forced&&h.handle.cancel())},dn=e=>{let{pause_reasons:t}=M.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);M.setState({pause_reasons:n}),N("resume",e),n.length===0&&z({type:"pause_change",paused:!1,reasons:n}),Y()},St=e=>M.getState().updates[e],gn=async e=>{var n,r;let t=St(e);ve.add(e);try{let a=await Se(e),s=(r=t==null?void 0:t.next_version)!=null?r:(n=ce(e))==null?void 0:n.version;return!a||!s||a.version!==s?!1:(M.setState(c=>{var o;let l={...c.updates};return delete l[e],{updates:l,apply_ticks:{...c.apply_ticks,[e]:((o=c.apply_ticks[e])!=null?o:0)+1}}}),N("updated",e,t==null?void 0:t.current_version,"\u2192",a.version),!0)}finally{ve.delete(e)}},fn=()=>Object.values(M.getState().catalog).map(e=>({...e,installed:!!w(e.app_id),removed_by_user:Q.has(e.app_id)})),ce=e=>M.getState().catalog[e],Se=async e=>{let t=ce(e);if(!t)return;if(F.delete(e),Q.delete(e),await Ie(t))return w(e);let n=w(e);if(wt(e)&&!ve.has(e)&&n&&await K(n))return n;let r=new Promise(a=>{var s;((s=ee[e])!=null?s:ee[e]=[]).push(a)});return(h==null?void 0:h.app_id)===e?h.forced=!0:(W[e]=0,_e(e,{front:!0}),h&&!h.forced?h.handle.cancel():Y(e)),r};import{Fragment as Et,jsx as T,jsxs as ue}from"react/jsx-runtime";var Be=e=>(e!=null?e:"").replace(/\?[^#]*/,""),bt=0,wn=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},vn=Ve.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:a,web_at_top:s,splash:c,bridge:l,opaque_background:o,onWebLoadEnd:d})=>{var Ye,Qe;let f=J(null),y=J(!1),A=H($,p=>p.instances[e]),u=A==null?void 0:A.app.app_id,I=A==null?void 0:A.app.manifest_url,v=A==null?void 0:A.context,x=A==null?void 0:A.url_params,[i,m]=te(()=>u?w(u):null),[U,j]=te(!1),[Rt,We]=te(0),[Pt,re]=te(0),[Ct,C]=te(!1),V=J(null),je=p=>{V.current&&clearTimeout(V.current),V.current=setTimeout(()=>{V.current=null,C(!0)},p)};B(()=>()=>{V.current&&clearTimeout(V.current)},[]),B(()=>{if(!u||!t&&i)return;let p=!0;return j(!1),(async()=>{let g=w(u),R=g?await K(g):!1;if(!p||(m(R?D=>!D||D.version!==g.version||D.permissions.join(",")!==g.permissions.join(",")?g:D:null),__DEV__&&Date.now()-bt>1e4&&(bt=Date.now(),await Ne()),!p))return;let q=await Se(u),G=q!==void 0?q:I?await At(u,I):w(u);if(p){if(!G){j(!0);return}m(D=>D!=null?D:G)}})(),()=>{p=!1}},[t,u,I,Rt]),B(()=>mt(e,p=>f.current?(f.current.postMessage(p),!0):!1),[e]);let kt=H(M,p=>{let g=u?p.downloads[u]:void 0;return(g==null?void 0:g.status)==="installed"?g.version:void 0});B(()=>{if(t||!u||!i)return;let p=w(u);if(!p||p.version===i.version)return;let g=!0;return K(p).then(R=>{!g||!R||(L(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",i.version,"\u2192",p.version),m(p))}),()=>{g=!1}},[t,u,kt,i==null?void 0:i.version]);let qe=H(M,p=>{var g;return u&&(g=p.apply_ticks[u])!=null?g:0});B(()=>{if(!qe||!u)return;let p=w(u);if(!p||p.version===(i==null?void 0:i.version))return;let g=!0;return K(p).then(R=>{!g||!R||(L(`webview:${e}`,"c\u1EADp nh\u1EADt",i==null?void 0:i.version,"\u2192",p.version),C(!1),m(p))}),()=>{g=!1}},[qe]),B(()=>{var R;let p=(R=S().keep_alive)==null?void 0:R.idle_close_ms;if(t||!p||p<=0)return;let g=setTimeout(()=>{Me(e)},p);return()=>clearTimeout(g)},[t,e]),B(()=>{a>0&&(j(!1),C(!1),re(p=>p+1),We(p=>p+1))},[a]);let Ke=J(t);B(()=>{var p;Ke.current!==t&&(Ke.current=t,y.current&&((p=f.current)==null||p.injectJavaScript(it(t?"resumed":"paused"))))},[t]);let de=`${(Ye=i==null?void 0:i.version)!=null?Ye:"none"}:${(Qe=i==null?void 0:i.permissions.join(","))!=null?Qe:""}:${Pt}`,oe=be(()=>JSON.stringify([v!=null?v:{},x!=null?x:{}]),[v,x]),xe=be(()=>{var p;return lt(x!=null?x:{},(p=i==null?void 0:i.permissions)!=null?p:[])},[oe,i==null?void 0:i.permissions]),Ot=be(()=>pt(v!=null?v:{},xe)+ot()+(S().debug?rt():""),[xe]),ge=J(null),ze=J(null);B(()=>{var g,R,q;if(!i)return;if(ze.current!==de){ze.current=de,ge.current=oe;return}if(ge.current===oe)return;let p=((R=JSON.parse((g=ge.current)!=null?g:"[]")[0])!=null?R:{}).org_id;if(ge.current=oe,p===(v==null?void 0:v.org_id)&&y.current){C(!1),je(1500),(q=f.current)==null||q.injectJavaScript(st(v!=null?v:{},xe));return}C(!1),re(G=>G+1)},[oe,i,de]);let It=Je(async p=>{var R,q,G,D,Ee;let g=et(p.nativeEvent.data);if(!g){if(u&&(l!=null&&l.onWebEvent))try{Promise.resolve(l.onWebEvent(p.nativeEvent.data,{app_id:u,instance_id:e})).catch(_=>{console.warn("[miniapp] onWebEvent l\u1ED7i",u,_)})}catch(_){console.warn("[miniapp] onWebEvent l\u1ED7i",u,_)}return}if(g.method==="log"){let{level:_,text:k}=g;L(`web:${e}`,_!=null?_:"log",k!=null?k:"");return}if(g.method==="pong"){V.current||C(!0);return}if(g.method==="touchAtTop"){s.emit(!!g.at_top);return}if(g.method==="contextApplied"){V.current&&clearTimeout(V.current),V.current=null,C(!0);return}if(g.method==="ready"){y.current=!0,C(!0);let _=(R=$.getState().instances[e])==null?void 0:R.context;_&&((q=f.current)==null||q.injectJavaScript(Ce(_)));return}try{let _=await ut(g,{getHostData:()=>{var k,X;return(X=(k=$.getState().instances[e])==null?void 0:k.host_data)!=null?X:{}},getPermissions:()=>{var k,X;return u?(X=(k=w(u))==null?void 0:k.permissions)!=null?X:[]:[]},is_dark:r,close:ae,app_id:u!=null?u:"",instance_id:e,options:l});g.id&&((G=f.current)==null||G.injectJavaScript(tt(g.id,_)))}catch(_){if(!g.id)return;let k=_==null?void 0:_.code,X=_ instanceof b?_:new b(typeof k=="string"?k:"HOST_ERROR",String((D=_==null?void 0:_.message)!=null?D:_));(Ee=f.current)==null||Ee.injectJavaScript(nt(g.id,X))}},[e,r,u,s,l]),Dt=Je(()=>{j(!1),re(p=>p+1),We(p=>p+1)},[]);return ue(Ue,{style:[He.absoluteFill,o&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&O.behind],pointerEvents:t?"auto":"none",children:[i?T(yn,{ref:f,source:{uri:i.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${i.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:Ot,onMessage:It,bounces:!1,overScrollMode:"never",onLoadStart:p=>{L(`webview:${e}`,"load start",Be(p.nativeEvent.url)),y.current=!1,C(!1)},onError:p=>{L(`webview:${e}`,"load error",Be(p.nativeEvent.url),p.nativeEvent.description),j(!0),C(!1)},onLoadEnd:p=>{let g=p.nativeEvent.url;L(`webview:${e}`,"load end",Be(g)),u&&(d==null||d({app_id:u,instance_id:e,url:g})),je(1500)},onContentProcessDidTerminate:()=>{y.current=!1,C(!1),re(p=>p+1)},onRenderProcessGone:()=>(y.current=!1,C(!1),re(p=>p+1),!0),style:O.webview},de):null,A&&T(Sn,{visible:!i||!Ct,interactive:U,children:T(_n,{splash:c,app:A.app,is_dark:r,error:U,has_bundle:!!i,retry:Dt})})]})}),_n=Ve.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:a,retry:s})=>{let c=e,l=$e(t.app_id),o=r?"error":!a&&(l==null?void 0:l.status)==="downloading"?"downloading":"loading";return T(c,{app:t,is_dark:n,status:o,progress:o==="downloading"?l==null?void 0:l.progress:void 0,retry:s})}),Sn=({visible:e,interactive:t,children:n})=>{let r=J(new Fe.Value(e?1:0)).current,[a,s]=te(e);return B(()=>{if(e){s(!0),r.setValue(1);return}let c=Fe.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return c.start(({finished:l})=>{l&&s(!1)}),()=>c.stop()},[e,r]),a?T(Fe.View,{style:[He.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},Tt=({app:e,is_dark:t,status:n,progress:r,retry:a})=>{let s=t?"#FAFAFA":"#18181B";return ue(Ue,{style:[O.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[T(Ue,{style:[O.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?T(mn,{source:{uri:e.icon},style:O.splash_icon_image}):T(le,{style:O.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),T(le,{style:[O.splash_name,{color:s}],children:e.name}),n==="error"?ue(Et,{children:[T(le,{style:O.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),T(Mn,{activeOpacity:.7,style:[O.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:a,children:T(le,{style:[O.retry_text,{color:s}],children:"Th\u1EED l\u1EA1i"})})]}):ue(Et,{children:[T(hn,{style:O.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&ue(le,{style:O.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},xt=(e,t)=>{let n=J(t),r=J(!1);__DEV__&&!r.current&&n.current!==t&&(r.current=!0,console.warn(`[miniapp] MiniAppHost prop "${e}" \u0111\u1ED5i gi\u1EEFa c\xE1c l\u1EA7n render \u2192 m\u1ECDi WebView b\u1ECB mount l\u1EA1i. Khai b\xE1o component b\xEAn ngo\xE0i render.`))},bn=({container:e,splash:t=Tt,is_dark:n=!1,bridge:r,close_on_back:a=!0,opaque_background:s=!0,onWebLoadEnd:c})=>{xt("container",e),xt("splash",t);let l=e,o=H($,i=>i.active_key),d=J(o);o&&(d.current=o);let f=H($,i=>Object.keys(i.instances).join("|")),y=H($,i=>{var m;return i.active_key?(m=i.instances[i.active_key])==null?void 0:m.app.name:void 0}),A=be(()=>f?f.split("|"):[],[f]),[u,I]=te({}),v=J(wn()).current;B(()=>{if(!o||!a)return;let i=An.addEventListener("hardwareBackPress",()=>(ae(),!0));return()=>i.remove()},[o,a]);let x=Je(()=>{let i=$.getState().active_key;i&&I(m=>({...m,[i]:(m[i]||0)+1}))},[]);return A.length?T(l,{visible:!!o,title:y!=null?y:"",is_dark:n,close:ae,reload:x,subscribeWebAtTop:v.subscribe,children:A.map(i=>T(vn,{instance_key:i,is_active:o===i,is_front:(o!=null?o:d.current)===i,is_dark:n,reload_tick:u[i]||0,web_at_top:v,splash:t,bridge:r,opaque_background:s,onWebLoadEnd:c},i))}):null},O=He.create({webview:{flex:1,backgroundColor:"transparent"},behind:{zIndex:-1},splash:{flex:1,alignItems:"center",justifyContent:"center",gap:12},splash_icon:{width:72,height:72,borderRadius:20,alignItems:"center",justifyContent:"center",overflow:"hidden"},splash_icon_image:{width:72,height:72},splash_letter:{fontSize:28,fontWeight:"700",color:"#1D4ED8"},splash_name:{fontSize:16,fontWeight:"600"},splash_hint:{color:"#71717A"},splash_spinner:{marginTop:8},retry_button:{marginTop:4,paddingHorizontal:20,paddingVertical:10,borderRadius:999},retry_text:{fontWeight:"600"}}),xn=Ve.memo(bn);export{Tt as DefaultMiniAppSplash,Te as MINIAPP_PLATFORM_URL,xn as MiniAppHost,b as MiniAppHostError,ae as closeMiniApp,Lt as configureMiniApp,Nt as createMmkvStorage,$t as createRnfsFileSystem,Se as ensureMiniApp,w as getLocalMiniApp,fn as getMiniAppCatalog,ce as getMiniAppCatalogEntry,rn as getMiniAppStatuses,St as getMiniAppUpdate,nn as onMiniAppEvent,Kt as openMiniApp,cn as pauseMiniApp,un as pauseMiniAppDownloads,zt as preloadMiniApp,pn as restoreMiniApp,ln as resumeMiniApp,dn as resumeMiniAppDownloads,Wt as sendEventToWeb,Ne as syncMiniAppCatalog,an as uninstallMiniApp,gn as updateMiniApp,$e as useMiniAppDownload,tn as useMiniAppDownloadsPaused};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retion-miniapp/react-native",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Host chạy Retion Mini App (bundle web) trong app React Native — chỉ cần react-native-webview",
5
5
  "license": "MIT",
6
6
  "repository": {