@retion-miniapp/react-native 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -182,9 +182,9 @@ interface MiniAppKeepAlive {
182
182
  /** Mini app đã đóng quá N ms → huỷ WebView (dừng timer / animation ngầm của web, tiết kiệm pin). */
183
183
  idle_close_ms?: number;
184
184
  }
185
+ /** Retion Mini App Platform (Vercel sin1 + Neon). Console: {MINIAPP_PLATFORM_URL}/console */
186
+ declare const MINIAPP_PLATFORM_URL = "https://retion-miniapp-platform.vercel.app";
185
187
  interface MiniAppConfig {
186
- /** Retion Mini App Platform, vd https://retion-miniapp-platform.vercel.app */
187
- platform_url: string;
188
188
  /** App ID của ứng dụng (Console → Ứng dụng). */
189
189
  host_id: string;
190
190
  /** Client Token của ứng dụng (Console → Ứng dụng → Thông tin tích hợp). */
@@ -267,6 +267,12 @@ interface MiniAppHostProps {
267
267
  * false: không bắt nút Back — dùng khi mini app là nội dung chính của màn / tab (đóng sẽ thành màn trống).
268
268
  */
269
269
  close_on_back?: boolean;
270
+ /**
271
+ * Tô nền đặc (trắng / #09090B theo is_dark) dưới mỗi WebView. Mặc định true: web không tự tô nền
272
+ * vẫn không lộ mini app khác đang chạy ngầm phía sau. false: nền trong suốt — container tự lo nền
273
+ * (vd. container có nền / hiệu ứng riêng muốn nhìn xuyên qua vùng web trống).
274
+ */
275
+ opaque_background?: boolean;
270
276
  /** WebView đã tải xong tài liệu local. Hữu ích để app cha ẩn launch splash sau khi mini app sẵn sàng hiện. */
271
277
  onWebLoadEnd?: (event: {
272
278
  app_id: string;
@@ -274,7 +280,7 @@ interface MiniAppHostProps {
274
280
  url: string;
275
281
  }) => void;
276
282
  }
277
- declare const _default: React.MemoExoticComponent<({ container, splash, is_dark, bridge, close_on_back, onWebLoadEnd }: MiniAppHostProps) => React.JSX.Element | null>;
283
+ declare const _default: React.MemoExoticComponent<({ container, splash, is_dark, bridge, close_on_back, opaque_background, onWebLoadEnd }: MiniAppHostProps) => React.JSX.Element | null>;
278
284
 
279
285
  interface OpenMiniAppArgs {
280
286
  app: MiniAppLaunch;
@@ -312,14 +318,53 @@ declare const closeMiniApp: () => void;
312
318
  *
313
319
  * Catalog (list manifest lần sync gần nhất) lưu storage → mở app offline vẫn biết app nào có bundle.
314
320
  */
315
- type MiniAppDownloadStatus = 'queued' | 'downloading' | 'installed' | 'failed';
321
+ /**
322
+ * Giống icon app trên iOS:
323
+ * - queued: chờ tới lượt (icon mờ) · downloading: tải lần đầu · updating: đã có bản cũ, đang tải bản mới
324
+ * - installed: mở được · failed: lỗi sau khi thử lại (has_local → vẫn mở bản cũ)
325
+ * - uninstalling: app không còn trong list, đang xoá
326
+ */
327
+ type MiniAppDownloadStatus = 'queued' | 'downloading' | 'updating' | 'installed' | 'failed' | 'uninstalling';
316
328
  interface MiniAppDownloadState {
317
329
  status: MiniAppDownloadStatus;
318
330
  /** 0–1 khi đang tải. */
319
331
  progress: number;
320
332
  version: string;
333
+ /** Máy đang có 1 bản (có thể cũ) → bấm mở được ngay. */
334
+ has_local: boolean;
321
335
  error?: string;
322
336
  }
337
+ type MiniAppEvent =
338
+ /** Status 1 app đổi (queued → downloading → installed …). */
339
+ {
340
+ type: 'status_change';
341
+ app_id: string;
342
+ state: MiniAppDownloadState;
343
+ }
344
+ /** % tải đổi (~250ms / lần). */
345
+ | {
346
+ type: 'progress';
347
+ app_id: string;
348
+ progress: number;
349
+ version: string;
350
+ }
351
+ /** App đã bị gỡ khỏi máy → Sảnh bỏ icon. */
352
+ | {
353
+ type: 'uninstalled';
354
+ app_id: string;
355
+ }
356
+ /** Sync list xong: app_ids = list hiện tại, removed = app bị gỡ. Hàng đợi vẫn đang tải tiếp. */
357
+ | {
358
+ type: 'sync_complete';
359
+ app_ids: string[];
360
+ removed: string[];
361
+ }
362
+ /** Hàng đợi chuyển dừng ↔ chạy (pauseMiniAppDownloads / resumeMiniAppDownloads). reasons = lý do còn lại. */
363
+ | {
364
+ type: 'pause_change';
365
+ paused: boolean;
366
+ reasons: string[];
367
+ };
323
368
  /** Manifest từ API list ứng dụng (bundle_url tuyệt đối). */
324
369
  type MiniAppCatalogEntry = MiniAppManifest & {
325
370
  name?: string;
@@ -329,11 +374,20 @@ type MiniAppCatalogEntry = MiniAppManifest & {
329
374
  declare const useMiniAppDownload: (app_id: string | undefined) => MiniAppDownloadState | undefined;
330
375
  /** Hàng đợi đang dừng (còn lý do pause). */
331
376
  declare const useMiniAppDownloadsPaused: () => boolean;
377
+ /** Nghe thay đổi status / % tải của mọi mini app (vd cập nhật icon ở Sảnh). Trả hàm huỷ. */
378
+ declare const onMiniAppEvent: (listener: (event: MiniAppEvent) => void) => () => void;
379
+ /** Status hiện tại của mọi mini app — đọc 1 lần khi vẽ Sảnh, sau đó nghe onMiniAppEvent. */
380
+ declare const getMiniAppStatuses: () => Record<string, MiniAppDownloadState>;
332
381
  /**
333
382
  * Lấy list mini app (theo config.channels — kênh đứng trước được ưu tiên) → cập nhật catalog
334
383
  * → cho app khác version vào hàng đợi. Lỗi mạng → giữ catalog cũ, không xoá gì.
335
384
  */
336
385
  declare const syncMiniAppCatalog: () => Promise<void>;
386
+ /**
387
+ * Gỡ mini app khỏi máy: bỏ khỏi hàng đợi, huỷ lượt tải đang chạy, xoá bundle, huỷ WebView (trừ khi
388
+ * đang mở). syncMiniAppCatalog tự gọi cho app không còn trong list; app còn trong list → lần sync sau tải lại.
389
+ */
390
+ declare const uninstallMiniApp: (app_id: string) => Promise<void>;
337
391
  /** Dừng hàng đợi vì `reason`. File đang tải (không phải do người dùng mở) bị huỷ, tải lại sau. */
338
392
  declare const pauseMiniAppDownloads: (reason: string) => void;
339
393
  /** Gỡ lý do dừng; hết lý do → chạy tiếp. */
@@ -361,4 +415,4 @@ declare class BridgeError extends Error {
361
415
  constructor(code: string, message: string);
362
416
  }
363
417
 
364
- export { DefaultMiniAppSplash, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, 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 OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalogEntry, openMiniApp, pauseMiniAppDownloads, preloadMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, useMiniAppDownload, useMiniAppDownloadsPaused };
418
+ export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, 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 OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalogEntry, getMiniAppStatuses, onMiniAppEvent, openMiniApp, pauseMiniAppDownloads, preloadMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
package/dist/index.d.ts CHANGED
@@ -182,9 +182,9 @@ interface MiniAppKeepAlive {
182
182
  /** Mini app đã đóng quá N ms → huỷ WebView (dừng timer / animation ngầm của web, tiết kiệm pin). */
183
183
  idle_close_ms?: number;
184
184
  }
185
+ /** Retion Mini App Platform (Vercel sin1 + Neon). Console: {MINIAPP_PLATFORM_URL}/console */
186
+ declare const MINIAPP_PLATFORM_URL = "https://retion-miniapp-platform.vercel.app";
185
187
  interface MiniAppConfig {
186
- /** Retion Mini App Platform, vd https://retion-miniapp-platform.vercel.app */
187
- platform_url: string;
188
188
  /** App ID của ứng dụng (Console → Ứng dụng). */
189
189
  host_id: string;
190
190
  /** Client Token của ứng dụng (Console → Ứng dụng → Thông tin tích hợp). */
@@ -267,6 +267,12 @@ interface MiniAppHostProps {
267
267
  * false: không bắt nút Back — dùng khi mini app là nội dung chính của màn / tab (đóng sẽ thành màn trống).
268
268
  */
269
269
  close_on_back?: boolean;
270
+ /**
271
+ * Tô nền đặc (trắng / #09090B theo is_dark) dưới mỗi WebView. Mặc định true: web không tự tô nền
272
+ * vẫn không lộ mini app khác đang chạy ngầm phía sau. false: nền trong suốt — container tự lo nền
273
+ * (vd. container có nền / hiệu ứng riêng muốn nhìn xuyên qua vùng web trống).
274
+ */
275
+ opaque_background?: boolean;
270
276
  /** WebView đã tải xong tài liệu local. Hữu ích để app cha ẩn launch splash sau khi mini app sẵn sàng hiện. */
271
277
  onWebLoadEnd?: (event: {
272
278
  app_id: string;
@@ -274,7 +280,7 @@ interface MiniAppHostProps {
274
280
  url: string;
275
281
  }) => void;
276
282
  }
277
- declare const _default: React.MemoExoticComponent<({ container, splash, is_dark, bridge, close_on_back, onWebLoadEnd }: MiniAppHostProps) => React.JSX.Element | null>;
283
+ declare const _default: React.MemoExoticComponent<({ container, splash, is_dark, bridge, close_on_back, opaque_background, onWebLoadEnd }: MiniAppHostProps) => React.JSX.Element | null>;
278
284
 
279
285
  interface OpenMiniAppArgs {
280
286
  app: MiniAppLaunch;
@@ -312,14 +318,53 @@ declare const closeMiniApp: () => void;
312
318
  *
313
319
  * Catalog (list manifest lần sync gần nhất) lưu storage → mở app offline vẫn biết app nào có bundle.
314
320
  */
315
- type MiniAppDownloadStatus = 'queued' | 'downloading' | 'installed' | 'failed';
321
+ /**
322
+ * Giống icon app trên iOS:
323
+ * - queued: chờ tới lượt (icon mờ) · downloading: tải lần đầu · updating: đã có bản cũ, đang tải bản mới
324
+ * - installed: mở được · failed: lỗi sau khi thử lại (has_local → vẫn mở bản cũ)
325
+ * - uninstalling: app không còn trong list, đang xoá
326
+ */
327
+ type MiniAppDownloadStatus = 'queued' | 'downloading' | 'updating' | 'installed' | 'failed' | 'uninstalling';
316
328
  interface MiniAppDownloadState {
317
329
  status: MiniAppDownloadStatus;
318
330
  /** 0–1 khi đang tải. */
319
331
  progress: number;
320
332
  version: string;
333
+ /** Máy đang có 1 bản (có thể cũ) → bấm mở được ngay. */
334
+ has_local: boolean;
321
335
  error?: string;
322
336
  }
337
+ type MiniAppEvent =
338
+ /** Status 1 app đổi (queued → downloading → installed …). */
339
+ {
340
+ type: 'status_change';
341
+ app_id: string;
342
+ state: MiniAppDownloadState;
343
+ }
344
+ /** % tải đổi (~250ms / lần). */
345
+ | {
346
+ type: 'progress';
347
+ app_id: string;
348
+ progress: number;
349
+ version: string;
350
+ }
351
+ /** App đã bị gỡ khỏi máy → Sảnh bỏ icon. */
352
+ | {
353
+ type: 'uninstalled';
354
+ app_id: string;
355
+ }
356
+ /** Sync list xong: app_ids = list hiện tại, removed = app bị gỡ. Hàng đợi vẫn đang tải tiếp. */
357
+ | {
358
+ type: 'sync_complete';
359
+ app_ids: string[];
360
+ removed: string[];
361
+ }
362
+ /** Hàng đợi chuyển dừng ↔ chạy (pauseMiniAppDownloads / resumeMiniAppDownloads). reasons = lý do còn lại. */
363
+ | {
364
+ type: 'pause_change';
365
+ paused: boolean;
366
+ reasons: string[];
367
+ };
323
368
  /** Manifest từ API list ứng dụng (bundle_url tuyệt đối). */
324
369
  type MiniAppCatalogEntry = MiniAppManifest & {
325
370
  name?: string;
@@ -329,11 +374,20 @@ type MiniAppCatalogEntry = MiniAppManifest & {
329
374
  declare const useMiniAppDownload: (app_id: string | undefined) => MiniAppDownloadState | undefined;
330
375
  /** Hàng đợi đang dừng (còn lý do pause). */
331
376
  declare const useMiniAppDownloadsPaused: () => boolean;
377
+ /** Nghe thay đổi status / % tải của mọi mini app (vd cập nhật icon ở Sảnh). Trả hàm huỷ. */
378
+ declare const onMiniAppEvent: (listener: (event: MiniAppEvent) => void) => () => void;
379
+ /** Status hiện tại của mọi mini app — đọc 1 lần khi vẽ Sảnh, sau đó nghe onMiniAppEvent. */
380
+ declare const getMiniAppStatuses: () => Record<string, MiniAppDownloadState>;
332
381
  /**
333
382
  * Lấy list mini app (theo config.channels — kênh đứng trước được ưu tiên) → cập nhật catalog
334
383
  * → cho app khác version vào hàng đợi. Lỗi mạng → giữ catalog cũ, không xoá gì.
335
384
  */
336
385
  declare const syncMiniAppCatalog: () => Promise<void>;
386
+ /**
387
+ * Gỡ mini app khỏi máy: bỏ khỏi hàng đợi, huỷ lượt tải đang chạy, xoá bundle, huỷ WebView (trừ khi
388
+ * đang mở). syncMiniAppCatalog tự gọi cho app không còn trong list; app còn trong list → lần sync sau tải lại.
389
+ */
390
+ declare const uninstallMiniApp: (app_id: string) => Promise<void>;
337
391
  /** Dừng hàng đợi vì `reason`. File đang tải (không phải do người dùng mở) bị huỷ, tải lại sau. */
338
392
  declare const pauseMiniAppDownloads: (reason: string) => void;
339
393
  /** Gỡ lý do dừng; hết lý do → chạy tiếp. */
@@ -361,4 +415,4 @@ declare class BridgeError extends Error {
361
415
  constructor(code: string, message: string);
362
416
  }
363
417
 
364
- export { DefaultMiniAppSplash, type MiniAppBridgeOptions, type MiniAppCatalogEntry, type MiniAppChannel, type MiniAppConfig, type MiniAppContainerProps, type MiniAppContext, type MiniAppDownloadState, type MiniAppDownloadStatus, type MiniAppDownloadTask, 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 OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalogEntry, openMiniApp, pauseMiniAppDownloads, preloadMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, useMiniAppDownload, useMiniAppDownloadsPaused };
418
+ export { DefaultMiniAppSplash, MINIAPP_PLATFORM_URL, type MiniAppBridgeOptions, type MiniAppCatalogEntry, 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 OpenMiniAppArgs, closeMiniApp, configureMiniApp, createMmkvStorage, createRnfsFileSystem, ensureMiniApp, getLocalMiniApp, getMiniAppCatalogEntry, getMiniAppStatuses, onMiniAppEvent, openMiniApp, pauseMiniAppDownloads, preloadMiniApp, resumeMiniAppDownloads, sendEventToWeb, syncMiniAppCatalog, uninstallMiniApp, useMiniAppDownload, useMiniAppDownloadsPaused };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Et=Object.create;var oe=Object.defineProperty;var Tt=Object.getOwnPropertyDescriptor;var Rt=Object.getOwnPropertyNames;var Ct=Object.getPrototypeOf,Pt=Object.prototype.hasOwnProperty;var Ot=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Rt(t))!Pt.call(e,o)&&o!==n&&oe(e,o,{get:()=>t[o],enumerable:!(r=Tt(t,o))||r.enumerable});return e};var Ie=(e,t,n)=>(n=e!=null?Et(Ct(e)):{},De(t||!e||!e.__esModule?oe(n,"default",{value:e,enumerable:!0}):n,e)),kt=e=>De(oe({},"__esModule",{value:!0}),e);var Kt={};Ot(Kt,{DefaultMiniAppSplash:()=>Ee,MiniAppHost:()=>Mt,MiniAppHostError:()=>v,closeMiniApp:()=>z,configureMiniApp:()=>Le,createMmkvStorage:()=>Je,createRnfsFileSystem:()=>Be,ensureMiniApp:()=>he,getLocalMiniApp:()=>E,getMiniAppCatalogEntry:()=>be,openMiniApp:()=>pt,pauseMiniAppDownloads:()=>ft,preloadMiniApp:()=>ct,resumeMiniAppDownloads:()=>ht,sendEventToWeb:()=>st,syncMiniAppCatalog:()=>fe,useMiniAppDownload:()=>ge,useMiniAppDownloadsPaused:()=>dt});module.exports=kt(Kt);var q=null,$e=new Set,Le=e=>{q=e,$e.forEach(t=>t())},x=()=>{if(!q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return q},Ne=e=>{$e.add(e),q&&e()},B=(...e)=>{q!=null&&q.debug&&console.log("[miniapp]",...e)};var Be=(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(o=>o.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:o})=>{let{jobId:a,promise:d}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:c,contentLength:i})=>o==null?void 0:o(c,i)});return{promise:d.then(({statusCode:c})=>({status:c})),cancel:()=>e.stopDownload(a)}}}),Je=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});var u=Ie(require("react")),w=require("react-native"),wt=Ie(require("react-native-webview"));var ie=require("react-native"),se=1,v=class extends Error{constructor(n,r){super(r);this.code=n}},Ve=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===se&&typeof t.method=="string"?t:null}catch{return null}},ae=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,We=(e,t)=>ae({id:e,result:t}),He=(e,t)=>ae({id:e,error:{code:t.code,message:t.message}}),ye=e=>ae({event:"context",data:e});var je=()=>`(function () {
1
+ "use strict";var $t=Object.create;var ae=Object.defineProperty;var Nt=Object.getOwnPropertyDescriptor;var Ft=Object.getOwnPropertyNames;var Bt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Vt=(e,t)=>{for(var n in t)ae(e,n,{get:t[n],enumerable:!0})},We=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ft(t))!Jt.call(e,s)&&s!==n&&ae(e,s,{get:()=>t[s],enumerable:!(r=Nt(t,s))||r.enumerable});return e};var je=(e,t,n)=>(n=e!=null?$t(Bt(e)):{},We(t||!e||!e.__esModule?ae(n,"default",{value:e,enumerable:!0}):n,e)),Wt=e=>We(ae({},"__esModule",{value:!0}),e);var rn={};Vt(rn,{DefaultMiniAppSplash:()=>Le,MINIAPP_PLATFORM_URL:()=>pe,MiniAppHost:()=>Rt,MiniAppHostError:()=>b,closeMiniApp:()=>Y,configureMiniApp:()=>qe,createMmkvStorage:()=>ze,createRnfsFileSystem:()=>Ke,ensureMiniApp:()=>_e,getLocalMiniApp:()=>T,getMiniAppCatalogEntry:()=>Ie,getMiniAppStatuses:()=>_t,onMiniAppEvent:()=>yt,openMiniApp:()=>mt,pauseMiniAppDownloads:()=>St,preloadMiniApp:()=>At,resumeMiniAppDownloads:()=>bt,sendEventToWeb:()=>ft,syncMiniAppCatalog:()=>ye,uninstallMiniApp:()=>ke,useMiniAppDownload:()=>Me,useMiniAppDownloadsPaused:()=>Mt});module.exports=Wt(rn);var pe="https://retion-miniapp-platform.vercel.app",q=null,He=new Set,qe=e=>{q=e,He.forEach(t=>t())},E=()=>{if(!q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return q},Ue=e=>{He.add(e),q&&e()},F=(...e)=>{q!=null&&q.debug&&console.log("[miniapp]",...e)};var Ke=(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:c}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:u,contentLength:a})=>s==null?void 0:s(u,a)});return{promise:c.then(({statusCode:u})=>({status:u})),cancel:()=>e.stopDownload(o)}}}),ze=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});var l=je(require("react")),w=require("react-native"),Tt=je(require("react-native-webview"));var ce=require("react-native"),le=1,b=class extends Error{constructor(n,r){super(r);this.code=n}},Ye=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===le&&typeof t.method=="string"?t:null}catch{return null}},ue=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,Ge=(e,t)=>ue({id:e,result:t}),Xe=(e,t)=>ue({id:e,error:{code:t.code,message:t.message}}),Ee=e=>ue({event:"context",data:e});var Ze=()=>`(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: ${se}, method: 'log', level: level, text: parts.join(' ') }));
11
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${le}, 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;`,qe=()=>`(function () {
22
+ })(); true;`,et=()=>`(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: ${se}, method: 'touchAtTop', at_top: at_top }));
33
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${le}, 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;`,Ue=e=>ae({event:e}),Ke=(e,t)=>{let n=ze(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
- ${ye(e)}`},ze=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),Qe=(e,t={})=>{let n=ze(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${se} };
41
+ })(); true;`,tt=e=>ue({event:e}),nt=(e,t)=>{let n=rt(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
+ ${Ee(e)}`},rt=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),ot=(e,t={})=>{let n=rt(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${le} };
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;`},Ye={partner:"partner_token",chatbox:"chatbox_token"},Ge=(e,t)=>{let n={...e};for(let r of Object.values(Ye))t.includes(r)||delete n[r];return n},we=new Set,Fe=async(e,t)=>{if(we.has(e))throw new v("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);we.add(e);try{return await t()}finally{we.delete(e)}},Me=(e,t)=>{if(typeof e!="string"||!e)throw new v("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},Xe=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:o,close:a,app_id:d,instance_id:c,options:i})=>{var b,A,T,p;let f=i==null?void 0:i.handlers,h={app_id:d,instance_id:c,close:a},g=()=>new v("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let l=f==null?void 0:f.requestPayment;if(!l)throw g();let _=t==null?void 0:t.amount;if(typeof _!="number"||!Number.isFinite(_)||_<=0)throw new v("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let R={...t,amount:_,currency:Me(t==null?void 0:t.currency,"currency")};return Fe(e,()=>l(R,h))}case"printImage":{let l=f==null?void 0:f.printImage;if(!l)throw g();let _=Me(t==null?void 0:t.image,"image");await Fe(e,()=>l({image:_},h));return}case"openScreen":if(!(f!=null&&f.openScreen))throw g();await f.openScreen({screen:Me(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},h);return;case"closeApp":a();return;case"openWebview":{let l=String((b=t==null?void 0:t.url)!=null?b:"");if(!/^https?:\/\//i.test(l))throw new v("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(i!=null&&i.openUrl?i.openUrl(l):ie.Linking.openURL(l));return}case"showToast":(T=i==null?void 0:i.showToast)==null||T.call(i,String((A=t==null?void 0:t.message)!=null?A:""));return;case"getSystemInfo":return{platform:ie.Platform.OS==="ios"?"ios":"android",appVersion:(p=i==null?void 0:i.app_version)!=null?p:"",theme:o?"dark":"light"};case"getAccessToken":{let l=n().access_token;if(!l)throw new v("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return l}case"getToken":{let l=t==null?void 0:t.type;if(l==="access"){let W=n().access_token;if(!W)throw new v("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return W}if(l!=="partner"&&l!=="chatbox")throw new v("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(l)}`);let _=Ye[l];if(!r().includes(_))throw new v("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${_} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let R=l==="partner"?n().partner_token:n().chatbox_token;if(!R)throw new v("HOST_ERROR",`Kh\xF4ng c\xF3 ${_}`);return R}case"getUserInfo":{let l=n().user;if(!l)throw new v("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return l}case"getPageInfo":{let l=n().page;if(!l)throw new v("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return l}case"sendMessage":case"insertText":throw new v("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new v("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var tt=e=>`bundle:${e}`,nt=()=>`${x().file_system.document_dir}/miniapps`,rt=(e,t,n="index.html",r=!1,o=[])=>{let a=`${nt()}/${e}/${t}`;return{app_id:e,version:t,dir:a,entry_uri:`file://${a}/${n}`,context_update:r,permissions:o}},Ze=e=>{var t;x().storage.setString(tt(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},Dt=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,E=e=>{let t=x().storage.getString(tt(e));if(!t)return null;try{let{version:n,entry:r,context_update:o,permissions:a}=JSON.parse(t);return rt(e,n,r,!!o,Array.isArray(a)?a:[])}catch{return null}},ce=e=>x().file_system.exists(e.entry_uri.replace("file://","")),_e=async e=>{let t=E(e.app_id);return(t==null?void 0:t.version)===e.version&&await ce(t)},It=async(e,t)=>{let n=x().file_system,r=`${nt()}/${e}`,o=await n.listDir(r).catch(()=>[]);await Promise.all(o.filter(a=>!t.includes(a)).map(a=>n.remove(`${r}/${a}`).catch(()=>{})))},K=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},pe={},ve=(e,{base_url:t,onProgress:n}={})=>{var b;let r=x().file_system,o=null,a=!1,d=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,c=()=>{if(a)throw new K},i=async()=>{var p;c();let A=E(e.app_id);if((A==null?void 0:A.version)===e.version&&await r.exists(A.dir))return Ze(e),E(e.app_id);c();let T=r.download({url:t?Dt(t,e.bundle_url):e.bundle_url,to_file:d,onProgress:(l,_)=>{var W;let R=_>0?_:(W=e.size)!=null?W:0;R>0&&(n==null||n(Math.min(1,l/R)))}});o=T;try{let{status:l}=await T.promise;if(c(),l!==200)throw new Error(`bundle ${l}`);if(e.sha256)if(r.sha256){if(await r.sha256(d)!==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);c();let _=rt(e.app_id,e.version,e.entry,!!e.context_update,(p=e.permissions)!=null?p:[]);return await r.remove(_.dir).catch(()=>{}),await r.mkdir(_.dir),await r.unzip(d,_.dir),Ze(e),It(e.app_id,[e.version,A==null?void 0:A.version].filter(Boolean)),_}catch(l){throw a?new K:l}finally{o=null,r.remove(d).catch(()=>{})}},h=((b=pe[e.app_id])!=null?b:Promise.resolve()).catch(()=>{}).then(i),g=h.catch(()=>{});return pe[e.app_id]=g,g.then(()=>{pe[e.app_id]===g&&delete pe[e.app_id]}),{promise:h,cancel:()=>{a=!0,o==null||o.cancel()}}},ee={},$t=__DEV__?0:60*1e3,et={},ot=(e,t)=>{var r,o;let n=E(e);return n&&Date.now()-((r=et[t])!=null?r:0)<$t?Promise.resolve(n):((o=ee[e])!=null||(ee[e]=(async()=>{let a=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!a.ok)throw new Error(`manifest ${a.status}`);let d=await a.json(),c=await ve(d,{base_url:t}).promise;return et[t]=Date.now(),c})().catch(a=>(console.warn("[miniapp] sync failed",e,a==null?void 0:a.message),E(e))).finally(()=>{ee[e]=void 0})),ee[e])};var le=new Map,it=(e,t)=>(le.set(e,t),()=>{le.get(e)===t&&le.delete(e)}),st=(e,t)=>{let n=le.get(e);return n?n(t):!1};var ue=require("react"),de=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let o=typeof r=="function"?r(t):r;t={...t,...o},n.forEach(a=>a())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},J=(e,t,n=Object.is)=>{let r=(0,ue.useRef)(null),o=()=>{let a=e.getState(),d=r.current;if(d&&d.state===a&&d.selector===t)return d.value;let c=t(a),i=d&&n(d.value,c)?d.value:c;return r.current={state:a,selector:t,value:i},i};return(0,ue.useSyncExternalStore)(e.subscribe,o)};var $=de({active_key:null,instances:{}}),at=({app:e,instance_id:t,context:n={},url_params:r={},host_data:o={}},a)=>{var c;let d=(c=x().keep_alive)==null?void 0:c.max_webviews;$.setState(i=>{let f=t!=null?t:e.app_id,h={...i.instances,[f]:{key:f,app:e,context:n,url_params:r,host_data:o,last_used_at:Date.now()}},g=Object.keys(h);return d&&d>0&&g.length>d&&g.filter(b=>b!==f).sort((b,A)=>h[b].last_used_at-h[A].last_used_at).slice(0,g.length-d).forEach(b=>{delete h[b]}),a?{active_key:f,instances:h}:{instances:h}})},pt=e=>at(e,!0),ct=e=>at(e,!1),z=()=>$.setState({active_key:null}),lt=e=>{$.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var ut="catalog",Lt=10*1e3,Nt=2,Bt=3e3,Jt=()=>{var e;try{return JSON.parse((e=x().storage.getString(ut))!=null?e:"{}")}catch{return{}}},C=de({catalog:{},downloads:{},pause_reasons:[]});Ne(()=>C.setState({catalog:Jt()}));var ge=e=>J(C,t=>e?t.downloads[e]:void 0),dt=()=>J(C,e=>e.pause_reasons.length>0),Y=(...e)=>B("queue",...e),L=[],Q={},S=null,U={},V=(e,t)=>{C.setState(n=>{let r=n.downloads[e];return{downloads:{...n.downloads,[e]:{...r!=null?r:{status:"queued",progress:0},...t}}}})},Se=(e,t)=>{var n;(n=U[e])==null||n.forEach(r=>r(t)),delete U[e]},Ft=()=>C.getState().pause_reasons.length>0,G=e=>{var c;if(S)return;let t=e?L.indexOf(e):Ft()?-1:0;if(t<0||t>=L.length)return;let[n]=L.splice(t,1),r=C.getState().catalog[n];if(!r){Se(n,E(n)),G();return}let o=Date.now();Q[n]=((c=Q[n])!=null?c:0)+1,V(n,{status:"downloading",progress:0,version:r.version,error:void 0});let a=0,d=ve(r,{onProgress:i=>{let f=Math.floor(i*100);f!==a&&(a=f,V(n,{progress:f/100,version:r.version}))}});S={app_id:n,handle:d,forced:!!e},Y("start",n,r.version,e?"(forced)":""),d.promise.then(i=>{Y("installed",n,r.version,`${Date.now()-o}ms`),V(n,{status:"installed",progress:1,version:r.version}),Se(n,i)}).catch(i=>{var h;if(i instanceof K){Y("paused",n),Q[n]-=1,L.unshift(n),V(n,{status:"queued",progress:0,version:r.version});return}let f=String((h=i==null?void 0:i.message)!=null?h:i);if(console.warn("[miniapp-queue] failed",n,f),Q[n]<Nt){V(n,{status:"queued",progress:0,version:r.version,error:f}),setTimeout(()=>{var g;L.includes(n)||(S==null?void 0:S.app_id)===n||(L.push(n),G((g=U[n])!=null&&g.length?n:void 0))},Bt);return}V(n,{status:"failed",progress:0,version:r.version,error:f}),Se(n,E(n))}).finally(()=>{S=null;let i=L.find(f=>{var h;return(h=U[f])==null?void 0:h.length});G(i)})},gt=(e,{front:t=!1}={})=>{if((S==null?void 0:S.app_id)===e)return;let n=L.indexOf(e);if(n>=0){if(!t)return;L.splice(n,1)}t?L.unshift(e):L.push(e)},Vt=async e=>{let{platform_url:t,host_id:n,client_token:r}=x(),o=new AbortController,a=setTimeout(()=>o.abort(),Lt);try{let d=`${t}/api/hosts/${encodeURIComponent(n)}/miniapps?channel=${e}`,c=await fetch(d,{headers:{Authorization:`Bearer ${r}`,"Cache-Control":"no-cache"},signal:o.signal});if(!c.ok)throw new Error(`host list ${e} ${c.status}`);return(await c.json()).apps.map(f=>({...f,channel:e}))}finally{clearTimeout(a)}},te=null,fe=()=>(te!=null||(te=(async()=>{let e=Date.now();try{let t=await Promise.all(x().channels.map(Vt)),n={};[...t].reverse().flat().forEach(o=>{n[o.app_id]=o}),x().storage.setString(ut,JSON.stringify(n)),C.setState({catalog:n});let r=[];for(let o of Object.values(n))await _e(o)?V(o.app_id,{status:"installed",progress:1,version:o.version}):r.push(o);r.forEach(o=>{Q[o.app_id]=0,V(o.app_id,{status:"queued",progress:0,version:o.version,error:void 0}),gt(o.app_id)}),Y("catalog",Object.keys(n).length,"apps, outdated",r.map(o=>o.app_id),`${Date.now()-e}ms`),G()}catch(t){console.warn("[miniapp-queue] sync catalog failed",t==null?void 0:t.message)}finally{te=null}})()),te),ft=e=>{let{pause_reasons:t}=C.getState();t.includes(e)||(C.setState({pause_reasons:[...t,e]}),Y("pause",e),S&&!S.forced&&S.handle.cancel())},ht=e=>{let{pause_reasons:t}=C.getState();t.includes(e)&&(C.setState({pause_reasons:t.filter(n=>n!==e)}),Y("resume",e),G())},be=e=>C.getState().catalog[e],he=async e=>{let t=be(e);if(!t)return;if(await _e(t))return E(e);let n=new Promise(r=>{var o;((o=U[e])!=null?o:U[e]=[]).push(r)});return(S==null?void 0:S.app_id)===e?S.forced=!0:(Q[e]=0,gt(e,{front:!0}),S&&!S.forced?S.handle.cancel():G(e)),n};var M=require("react/jsx-runtime"),xe=e=>(e!=null?e:"").replace(/\?[^#]*/,""),mt=0,Wt=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},Ht=u.default.memo(({instance_key:e,is_active:t,is_dark:n,reload_tick:r,web_at_top:o,splash:a,bridge:d,onWebLoadEnd:c})=>{var Oe,ke;let i=(0,u.useRef)(null),f=(0,u.useRef)(!1),h=J($,s=>s.instances[e]),g=h==null?void 0:h.app.app_id,b=h==null?void 0:h.app.manifest_url,A=h==null?void 0:h.context,T=h==null?void 0:h.url_params,[p,l]=(0,u.useState)(()=>g?E(g):null),[_,R]=(0,u.useState)(!1),[W,Te]=(0,u.useState)(0),[yt,X]=(0,u.useState)(0),[_t,D]=(0,u.useState)(!1),N=(0,u.useRef)(null),Re=s=>{N.current&&clearTimeout(N.current),N.current=setTimeout(()=>{N.current=null,D(!0)},s)};(0,u.useEffect)(()=>()=>{N.current&&clearTimeout(N.current)},[]),(0,u.useEffect)(()=>{if(!g||!t&&p)return;let s=!0;return R(!1),(async()=>{let m=E(g),P=m?await ce(m):!1;if(!s||(l(P?I=>!I||I.version!==m.version||I.permissions.join(",")!==m.permissions.join(",")?m:I:null),__DEV__&&Date.now()-mt>1e4&&(mt=Date.now(),await fe()),!s))return;let F=await he(g),H=F!==void 0?F:b?await ot(g,b):E(g);if(s){if(!H){R(!0);return}l(I=>I!=null?I:H)}})(),()=>{s=!1}},[t,g,b,W]),(0,u.useEffect)(()=>it(e,s=>i.current?(i.current.postMessage(s),!0):!1),[e]);let vt=J(C,s=>{let m=g?s.downloads[g]:void 0;return(m==null?void 0:m.status)==="installed"?m.version:void 0});(0,u.useEffect)(()=>{if(t||!g||!p)return;let s=E(g);if(!s||s.version===p.version)return;let m=!0;return ce(s).then(P=>{!m||!P||(B(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",p.version,"\u2192",s.version),l(s))}),()=>{m=!1}},[t,g,vt,p==null?void 0:p.version]),(0,u.useEffect)(()=>{var P;let s=(P=x().keep_alive)==null?void 0:P.idle_close_ms;if(t||!s||s<=0)return;let m=setTimeout(()=>{lt(e)},s);return()=>clearTimeout(m)},[t,e]),(0,u.useEffect)(()=>{r>0&&(R(!1),D(!1),X(s=>s+1),Te(s=>s+1))},[r]);let Ce=(0,u.useRef)(t);(0,u.useEffect)(()=>{var s;Ce.current!==t&&(Ce.current=t,f.current&&((s=i.current)==null||s.injectJavaScript(Ue(t?"resumed":"paused"))))},[t]);let ne=`${(Oe=p==null?void 0:p.version)!=null?Oe:"none"}:${(ke=p==null?void 0:p.permissions.join(","))!=null?ke:""}:${yt}`,Z=(0,u.useMemo)(()=>JSON.stringify([A!=null?A:{},T!=null?T:{}]),[A,T]),me=(0,u.useMemo)(()=>{var s;return Ge(T!=null?T:{},(s=p==null?void 0:p.permissions)!=null?s:[])},[Z,p==null?void 0:p.permissions]),St=(0,u.useMemo)(()=>Qe(A!=null?A:{},me)+qe()+(x().debug?je():""),[me]),re=(0,u.useRef)(null),Pe=(0,u.useRef)(null);(0,u.useEffect)(()=>{var m,P,F;if(!p)return;if(Pe.current!==ne){Pe.current=ne,re.current=Z;return}if(re.current===Z)return;let s=((P=JSON.parse((m=re.current)!=null?m:"[]")[0])!=null?P:{}).org_id;if(re.current=Z,s===(A==null?void 0:A.org_id)&&f.current){D(!1),Re(1500),(F=i.current)==null||F.injectJavaScript(Ke(A!=null?A:{},me));return}D(!1),X(H=>H+1)},[Z,p,ne]);let bt=(0,u.useCallback)(async s=>{var P,F,H,I,Ae;let m=Ve(s.nativeEvent.data);if(!m){if(g&&(d!=null&&d.onWebEvent))try{Promise.resolve(d.onWebEvent(s.nativeEvent.data,{app_id:g,instance_id:e})).catch(y=>{console.warn("[miniapp] onWebEvent l\u1ED7i",g,y)})}catch(y){console.warn("[miniapp] onWebEvent l\u1ED7i",g,y)}return}if(m.method==="log"){let{level:y,text:O}=m;B(`web:${e}`,y!=null?y:"log",O!=null?O:"");return}if(m.method==="pong"){N.current||D(!0);return}if(m.method==="touchAtTop"){o.emit(!!m.at_top);return}if(m.method==="contextApplied"){N.current&&clearTimeout(N.current),N.current=null,D(!0);return}if(m.method==="ready"){f.current=!0,D(!0);let y=(P=$.getState().instances[e])==null?void 0:P.context;y&&((F=i.current)==null||F.injectJavaScript(ye(y)));return}try{let y=await Xe(m,{getHostData:()=>{var O,j;return(j=(O=$.getState().instances[e])==null?void 0:O.host_data)!=null?j:{}},getPermissions:()=>{var O,j;return g?(j=(O=E(g))==null?void 0:O.permissions)!=null?j:[]:[]},is_dark:n,close:z,app_id:g!=null?g:"",instance_id:e,options:d});m.id&&((H=i.current)==null||H.injectJavaScript(We(m.id,y)))}catch(y){if(!m.id)return;let O=y==null?void 0:y.code,j=y instanceof v?y:new v(typeof O=="string"?O:"HOST_ERROR",String((I=y==null?void 0:y.message)!=null?I:y));(Ae=i.current)==null||Ae.injectJavaScript(He(m.id,j))}},[e,n,g,o,d]),xt=(0,u.useCallback)(()=>{R(!1),X(s=>s+1),Te(s=>s+1)},[]);return(0,M.jsxs)(w.View,{style:[w.StyleSheet.absoluteFill,!t&&k.behind],pointerEvents:t?"auto":"none",children:[p?(0,M.jsx)(wt.default,{ref:i,source:{uri:p.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${p.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:St,onMessage:bt,bounces:!1,overScrollMode:"never",onLoadStart:s=>{B(`webview:${e}`,"load start",xe(s.nativeEvent.url)),f.current=!1,D(!1)},onError:s=>{B(`webview:${e}`,"load error",xe(s.nativeEvent.url),s.nativeEvent.description),R(!0),D(!1)},onLoadEnd:s=>{let m=s.nativeEvent.url;B(`webview:${e}`,"load end",xe(m)),g&&(c==null||c({app_id:g,instance_id:e,url:m})),Re(1500)},onContentProcessDidTerminate:()=>{f.current=!1,D(!1),X(s=>s+1)},onRenderProcessGone:()=>(f.current=!1,D(!1),X(s=>s+1),!0),style:k.webview},ne):null,h&&(0,M.jsx)(qt,{visible:!p||!_t,interactive:_,children:(0,M.jsx)(jt,{splash:a,app:h.app,is_dark:n,error:_,has_bundle:!!p,retry:xt})})]})}),jt=u.default.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:o,retry:a})=>{let d=e,c=ge(t.app_id),i=r?"error":!o&&(c==null?void 0:c.status)==="downloading"?"downloading":"loading";return(0,M.jsx)(d,{app:t,is_dark:n,status:i,progress:i==="downloading"?c==null?void 0:c.progress:void 0,retry:a})}),qt=({visible:e,interactive:t,children:n})=>{let r=(0,u.useRef)(new w.Animated.Value(e?1:0)).current,[o,a]=(0,u.useState)(e);return(0,u.useEffect)(()=>{if(e){a(!0),r.setValue(1);return}let d=w.Animated.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return d.start(({finished:c})=>{c&&a(!1)}),()=>d.stop()},[e,r]),o?(0,M.jsx)(w.Animated.View,{style:[w.StyleSheet.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},Ee=({app:e,is_dark:t,status:n,progress:r,retry:o})=>{let a=t?"#FAFAFA":"#18181B";return(0,M.jsxs)(w.View,{style:[k.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[(0,M.jsx)(w.View,{style:[k.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?(0,M.jsx)(w.Image,{source:{uri:e.icon},style:k.splash_icon_image}):(0,M.jsx)(w.Text,{style:k.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),(0,M.jsx)(w.Text,{style:[k.splash_name,{color:a}],children:e.name}),n==="error"?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(w.Text,{style:k.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),(0,M.jsx)(w.TouchableOpacity,{activeOpacity:.7,style:[k.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:o,children:(0,M.jsx)(w.Text,{style:[k.retry_text,{color:a}],children:"Th\u1EED l\u1EA1i"})})]}):(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(w.ActivityIndicator,{style:k.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&(0,M.jsxs)(w.Text,{style:k.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},At=(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.`))},Ut=({container:e,splash:t=Ee,is_dark:n=!1,bridge:r,close_on_back:o=!0,onWebLoadEnd:a})=>{At("container",e),At("splash",t);let d=e,c=J($,p=>p.active_key),i=J($,p=>Object.keys(p.instances).join("|")),f=J($,p=>{var l;return p.active_key?(l=p.instances[p.active_key])==null?void 0:l.app.name:void 0}),h=(0,u.useMemo)(()=>i?i.split("|"):[],[i]),[g,b]=(0,u.useState)({}),A=(0,u.useRef)(Wt()).current;(0,u.useEffect)(()=>{if(!c||!o)return;let p=w.BackHandler.addEventListener("hardwareBackPress",()=>(z(),!0));return()=>p.remove()},[c,o]);let T=(0,u.useCallback)(()=>{let p=$.getState().active_key;p&&b(l=>({...l,[p]:(l[p]||0)+1}))},[]);return h.length?(0,M.jsx)(d,{visible:!!c,title:f!=null?f:"",is_dark:n,close:z,reload:T,subscribeWebAtTop:A.subscribe,children:h.map(p=>(0,M.jsx)(Ht,{instance_key:p,is_active:c===p,is_dark:n,reload_tick:g[p]||0,web_at_top:A,splash:t,bridge:r,onWebLoadEnd:a},p))}):null},k=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"}}),Mt=u.default.memo(Ut);0&&(module.exports={DefaultMiniAppSplash,MiniAppHost,MiniAppHostError,closeMiniApp,configureMiniApp,createMmkvStorage,createRnfsFileSystem,ensureMiniApp,getLocalMiniApp,getMiniAppCatalogEntry,openMiniApp,pauseMiniAppDownloads,preloadMiniApp,resumeMiniAppDownloads,sendEventToWeb,syncMiniAppCatalog,useMiniAppDownload,useMiniAppDownloadsPaused});
45
+ true;`},it={partner:"partner_token",chatbox:"chatbox_token"},st=(e,t)=>{let n={...e};for(let r of Object.values(it))t.includes(r)||delete n[r];return n},be=new Set,Qe=async(e,t)=>{if(be.has(e))throw new b("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);be.add(e);try{return await t()}finally{be.delete(e)}},xe=(e,t)=>{if(typeof e!="string"||!e)throw new b("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},at=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:s,close:o,app_id:c,instance_id:u,options:a})=>{var A,g,I,v;let h=a==null?void 0:a.handlers,m={app_id:c,instance_id:u,close:o},M=()=>new b("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let d=h==null?void 0:h.requestPayment;if(!d)throw M();let i=t==null?void 0:t.amount;if(typeof i!="number"||!Number.isFinite(i)||i<=0)throw new b("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let x={...t,amount:i,currency:xe(t==null?void 0:t.currency,"currency")};return Qe(e,()=>d(x,m))}case"printImage":{let d=h==null?void 0:h.printImage;if(!d)throw M();let i=xe(t==null?void 0:t.image,"image");await Qe(e,()=>d({image:i},m));return}case"openScreen":if(!(h!=null&&h.openScreen))throw M();await h.openScreen({screen:xe(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},m);return;case"closeApp":o();return;case"openWebview":{let d=String((A=t==null?void 0:t.url)!=null?A:"");if(!/^https?:\/\//i.test(d))throw new b("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(a!=null&&a.openUrl?a.openUrl(d):ce.Linking.openURL(d));return}case"showToast":(I=a==null?void 0:a.showToast)==null||I.call(a,String((g=t==null?void 0:t.message)!=null?g:""));return;case"getSystemInfo":return{platform:ce.Platform.OS==="ios"?"ios":"android",appVersion:(v=a==null?void 0:a.app_version)!=null?v:"",theme:s?"dark":"light"};case"getAccessToken":{let d=n().access_token;if(!d)throw new b("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 V=n().access_token;if(!V)throw new b("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return V}if(d!=="partner"&&d!=="chatbox")throw new b("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(d)}`);let i=it[d];if(!r().includes(i))throw new b("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${i} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let x=d==="partner"?n().partner_token:n().chatbox_token;if(!x)throw new b("HOST_ERROR",`Kh\xF4ng c\xF3 ${i}`);return x}case"getUserInfo":{let d=n().user;if(!d)throw new b("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 b("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return d}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 Te=e=>`bundle:${e}`,Re=()=>`${E().file_system.document_dir}/miniapps`,lt=(e,t,n="index.html",r=!1,s=[])=>{let o=`${Re()}/${e}/${t}`;return{app_id:e,version:t,dir:o,entry_uri:`file://${o}/${n}`,context_update:r,permissions:s}},pt=e=>{var t;E().storage.setString(Te(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},jt=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,T=e=>{let t=E().storage.getString(Te(e));if(!t)return null;try{let{version:n,entry:r,context_update:s,permissions:o}=JSON.parse(t);return lt(e,n,r,!!s,Array.isArray(o)?o:[])}catch{return null}},de=e=>E().file_system.exists(e.entry_uri.replace("file://","")),Pe=async e=>{let t=T(e.app_id);return(t==null?void 0:t.version)===e.version&&await de(t)},Ht=async(e,t)=>{let n=E().file_system,r=`${Re()}/${e}`,s=await n.listDir(r).catch(()=>[]);await Promise.all(s.filter(o=>!t.includes(o)).map(o=>n.remove(`${r}/${o}`).catch(()=>{})))},ut=async e=>{var t;await((t=re[e])==null?void 0:t.catch(()=>{})),E().storage.setString(Te(e),""),await E().file_system.remove(`${Re()}/${e}`).catch(()=>{})},Q=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},re={},Ce=(e,{base_url:t,onProgress:n}={})=>{var A;let r=E().file_system,s=null,o=!1,c=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,u=()=>{if(o)throw new Q},a=async()=>{var v;u();let g=T(e.app_id);if((g==null?void 0:g.version)===e.version&&await r.exists(g.dir))return pt(e),T(e.app_id);u();let I=r.download({url:t?jt(t,e.bundle_url):e.bundle_url,to_file:c,onProgress:(d,i)=>{var V;let x=i>0?i:(V=e.size)!=null?V:0;x>0&&(n==null||n(Math.min(1,d/x)))}});s=I;try{let{status:d}=await I.promise;if(u(),d!==200)throw new Error(`bundle ${d}`);if(e.sha256)if(r.sha256){if(await r.sha256(c)!==e.sha256)throw new Error("sha256 mismatch")}else F("b\u1ECF qua ki\u1EC3m tra sha256 (file_system kh\xF4ng c\xF3 sha256)",e.app_id);u();let i=lt(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),pt(e),Ht(e.app_id,[e.version,g==null?void 0:g.version].filter(Boolean)),i}catch(d){throw o?new Q:d}finally{s=null,r.remove(c).catch(()=>{})}},m=((A=re[e.app_id])!=null?A:Promise.resolve()).catch(()=>{}).then(a),M=m.catch(()=>{});return re[e.app_id]=M,M.then(()=>{re[e.app_id]===M&&delete re[e.app_id]}),{promise:m,cancel:()=>{o=!0,s==null||s.cancel()}}},ne={},qt=__DEV__?0:60*1e3,ct={},dt=(e,t)=>{var r,s;let n=T(e);return n&&Date.now()-((r=ct[t])!=null?r:0)<qt?Promise.resolve(n):((s=ne[e])!=null||(ne[e]=(async()=>{let o=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!o.ok)throw new Error(`manifest ${o.status}`);let c=await o.json(),u=await Ce(c,{base_url:t}).promise;return ct[t]=Date.now(),u})().catch(o=>(console.warn("[miniapp] sync failed",e,o==null?void 0:o.message),T(e))).finally(()=>{ne[e]=void 0})),ne[e])};var ge=new Map,gt=(e,t)=>(ge.set(e,t),()=>{ge.get(e)===t&&ge.delete(e)}),ft=(e,t)=>{let n=ge.get(e);return n?n(t):!1};var fe=require("react"),he=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)})}},B=(e,t,n=Object.is)=>{let r=(0,fe.useRef)(null),s=()=>{let o=e.getState(),c=r.current;if(c&&c.state===o&&c.selector===t)return c.value;let u=t(o),a=c&&n(c.value,u)?c.value:u;return r.current={state:o,selector:t,value:a},a};return(0,fe.useSyncExternalStore)(e.subscribe,s)};var $=he({active_key:null,instances:{}}),ht=({app:e,instance_id:t,context:n={},url_params:r={},host_data:s={}},o)=>{var u;let c=(u=E().keep_alive)==null?void 0:u.max_webviews;$.setState(a=>{let h=t!=null?t:e.app_id,m={...a.instances,[h]:{key:h,app:e,context:n,url_params:r,host_data:s,last_used_at:Date.now()}},M=Object.keys(m);return c&&c>0&&M.length>c&&M.filter(A=>A!==h).sort((A,g)=>m[A].last_used_at-m[g].last_used_at).slice(0,M.length-c).forEach(A=>{delete m[A]}),o?{active_key:h,instances:m}:{instances:m}})},mt=e=>ht(e,!0),At=e=>ht(e,!1),Y=()=>$.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 wt="catalog",Ut=10*1e3,Kt=2,zt=3e3,Qt=()=>{var e;try{return JSON.parse((e=E().storage.getString(wt))!=null?e:"{}")}catch{return{}}},R=he({catalog:{},downloads:{},pause_reasons:[]});Ue(()=>R.setState({catalog:Qt()}));var Me=e=>B(R,t=>e?t.downloads[e]:void 0),Mt=()=>B(R,e=>e.pause_reasons.length>0),K=(...e)=>F("queue",...e),P=[],U={},_=null,Ae=new Set,z={},Oe=new Set,X=e=>{Oe.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},yt=e=>(Oe.add(e),()=>{Oe.delete(e)}),_t=()=>R.getState().downloads,J=(e,t)=>{let n=!!T(e),r=R.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};R.setState(c=>({downloads:{...c.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=z[e])==null||n.forEach(r=>r(t)),delete z[e]},Yt=()=>R.getState().pause_reasons.length>0,G=e=>{var u;if(_)return;let t=e?P.indexOf(e):Yt()?-1:0;if(t<0||t>=P.length)return;let[n]=P.splice(t,1),r=R.getState().catalog[n];if(!r){we(n,T(n)),G();return}let s=Date.now();U[n]=((u=U[n])!=null?u:0)+1,J(n,{status:"downloading",progress:0,version:r.version,error:void 0});let o=0,c=Ce(r,{onProgress:a=>{let h=Math.floor(a*100);h!==o&&(o=h,J(n,{progress:h/100,version:r.version}))}});_={app_id:n,handle:c,forced:!!e},K("start",n,r.version,e?"(forced)":""),c.promise.then(a=>{K("installed",n,r.version,`${Date.now()-s}ms`),J(n,{status:"installed",progress:1,version:r.version}),we(n,a)}).catch(a=>{var m;if(a instanceof Q){if(Ae.has(n))return;K("paused",n),U[n]-=1,P.unshift(n),J(n,{status:"queued",progress:0,version:r.version});return}let h=String((m=a==null?void 0:a.message)!=null?m:a);if(console.warn("[miniapp-queue] failed",n,h),U[n]<Kt){J(n,{status:"queued",progress:0,version:r.version,error:h}),setTimeout(()=>{var M;P.includes(n)||(_==null?void 0:_.app_id)===n||(P.push(n),G((M=z[n])!=null&&M.length?n:void 0))},zt);return}J(n,{status:"failed",progress:0,version:r.version,error:h}),we(n,T(n))}).finally(()=>{_=null;let a=P.find(h=>{var m;return(m=z[h])==null?void 0:m.length});G(a)})},vt=(e,{front:t=!1}={})=>{if((_==null?void 0:_.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)},Gt=async e=>{let{host_id:t,client_token:n}=E(),r=new AbortController,s=setTimeout(()=>r.abort(),Ut);try{let o=`${pe}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,c=await fetch(o,{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(a=>({...a,channel:e}))}finally{clearTimeout(s)}},oe=null,ye=()=>(oe!=null||(oe=(async()=>{let e=Date.now();try{let t=await Promise.all(E().channels.map(Gt)),n={};[...t].reverse().flat().forEach(o=>{n[o.app_id]=o});let r=Object.keys(R.getState().catalog).filter(o=>!n[o]);E().storage.setString(wt,JSON.stringify(n)),R.setState({catalog:n}),await Promise.all(r.map(ke));let s=[];for(let o of Object.values(n))await Pe(o)?J(o.app_id,{status:"installed",progress:1,version:o.version}):s.push(o);s.forEach(o=>{U[o.app_id]=0,J(o.app_id,{status:"queued",progress:0,version:o.version,error:void 0}),vt(o.app_id)}),K("catalog",Object.keys(n).length,"apps, outdated",s.map(o=>o.app_id),"removed",r,`${Date.now()-e}ms`),X({type:"sync_complete",app_ids:Object.keys(n),removed:r}),G()}catch(t){console.warn("[miniapp-queue] sync catalog failed",t==null?void 0:t.message)}finally{oe=null}})()),oe),ke=async e=>{var r,s,o,c;if(Ae.has(e))return;Ae.add(e);let t=P.indexOf(e);t>=0&&P.splice(t,1),(_==null?void 0:_.app_id)===e&&_.handle.cancel();let n=(c=(o=(r=R.getState().downloads[e])==null?void 0:r.version)!=null?o:(s=T(e))==null?void 0:s.version)!=null?c:"";J(e,{status:"uninstalling",progress:0,version:n}),await ut(e),me(e),R.setState(u=>{let a={...u.downloads};return delete a[e],{downloads:a}}),delete U[e],Ae.delete(e),we(e,null),K("uninstalled",e),X({type:"uninstalled",app_id:e})},St=e=>{let{pause_reasons:t}=R.getState();t.includes(e)||(R.setState({pause_reasons:[...t,e]}),K("pause",e),t.length===0&&X({type:"pause_change",paused:!0,reasons:[e]}),_&&!_.forced&&_.handle.cancel())},bt=e=>{let{pause_reasons:t}=R.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);R.setState({pause_reasons:n}),K("resume",e),n.length===0&&X({type:"pause_change",paused:!1,reasons:n}),G()},Ie=e=>R.getState().catalog[e],_e=async e=>{let t=Ie(e);if(!t)return;if(await Pe(t))return T(e);let n=new Promise(r=>{var s;((s=z[e])!=null?s:z[e]=[]).push(r)});return(_==null?void 0:_.app_id)===e?_.forced=!0:(U[e]=0,vt(e,{front:!0}),_&&!_.forced?_.handle.cancel():G(e)),n};var y=require("react/jsx-runtime"),De=e=>(e!=null?e:"").replace(/\?[^#]*/,""),xt=0,Xt=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},Zt=l.default.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:s,web_at_top:o,splash:c,bridge:u,opaque_background:a,onWebLoadEnd:h})=>{var Je,Ve;let m=(0,l.useRef)(null),M=(0,l.useRef)(!1),A=B($,p=>p.instances[e]),g=A==null?void 0:A.app.app_id,I=A==null?void 0:A.app.manifest_url,v=A==null?void 0:A.context,d=A==null?void 0:A.url_params,[i,x]=(0,l.useState)(()=>g?T(g):null),[V,Z]=(0,l.useState)(!1),[Pt,$e]=(0,l.useState)(0),[Ct,ee]=(0,l.useState)(0),[Ot,D]=(0,l.useState)(!1),N=(0,l.useRef)(null),Ne=p=>{N.current&&clearTimeout(N.current),N.current=setTimeout(()=>{N.current=null,D(!0)},p)};(0,l.useEffect)(()=>()=>{N.current&&clearTimeout(N.current)},[]),(0,l.useEffect)(()=>{if(!g||!t&&i)return;let p=!0;return Z(!1),(async()=>{let f=T(g),C=f?await de(f):!1;if(!p||(x(C?L=>!L||L.version!==f.version||L.permissions.join(",")!==f.permissions.join(",")?f:L:null),__DEV__&&Date.now()-xt>1e4&&(xt=Date.now(),await ye()),!p))return;let W=await _e(g),j=W!==void 0?W:I?await dt(g,I):T(g);if(p){if(!j){Z(!0);return}x(L=>L!=null?L:j)}})(),()=>{p=!1}},[t,g,I,Pt]),(0,l.useEffect)(()=>gt(e,p=>m.current?(m.current.postMessage(p),!0):!1),[e]);let kt=B(R,p=>{let f=g?p.downloads[g]:void 0;return(f==null?void 0:f.status)==="installed"?f.version:void 0});(0,l.useEffect)(()=>{if(t||!g||!i)return;let p=T(g);if(!p||p.version===i.version)return;let f=!0;return de(p).then(C=>{!f||!C||(F(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",i.version,"\u2192",p.version),x(p))}),()=>{f=!1}},[t,g,kt,i==null?void 0:i.version]),(0,l.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(()=>{me(e)},p);return()=>clearTimeout(f)},[t,e]),(0,l.useEffect)(()=>{s>0&&(Z(!1),D(!1),ee(p=>p+1),$e(p=>p+1))},[s]);let Fe=(0,l.useRef)(t);(0,l.useEffect)(()=>{var p;Fe.current!==t&&(Fe.current=t,M.current&&((p=m.current)==null||p.injectJavaScript(tt(t?"resumed":"paused"))))},[t]);let ie=`${(Je=i==null?void 0:i.version)!=null?Je:"none"}:${(Ve=i==null?void 0:i.permissions.join(","))!=null?Ve:""}:${Ct}`,te=(0,l.useMemo)(()=>JSON.stringify([v!=null?v:{},d!=null?d:{}]),[v,d]),ve=(0,l.useMemo)(()=>{var p;return st(d!=null?d:{},(p=i==null?void 0:i.permissions)!=null?p:[])},[te,i==null?void 0:i.permissions]),It=(0,l.useMemo)(()=>ot(v!=null?v:{},ve)+et()+(E().debug?Ze():""),[ve]),se=(0,l.useRef)(null),Be=(0,l.useRef)(null);(0,l.useEffect)(()=>{var f,C,W;if(!i)return;if(Be.current!==ie){Be.current=ie,se.current=te;return}if(se.current===te)return;let p=((C=JSON.parse((f=se.current)!=null?f:"[]")[0])!=null?C:{}).org_id;if(se.current=te,p===(v==null?void 0:v.org_id)&&M.current){D(!1),Ne(1500),(W=m.current)==null||W.injectJavaScript(nt(v!=null?v:{},ve));return}D(!1),ee(j=>j+1)},[te,i,ie]);let Dt=(0,l.useCallback)(async p=>{var C,W,j,L,Se;let f=Ye(p.nativeEvent.data);if(!f){if(g&&(u!=null&&u.onWebEvent))try{Promise.resolve(u.onWebEvent(p.nativeEvent.data,{app_id:g,instance_id:e})).catch(S=>{console.warn("[miniapp] onWebEvent l\u1ED7i",g,S)})}catch(S){console.warn("[miniapp] onWebEvent l\u1ED7i",g,S)}return}if(f.method==="log"){let{level:S,text:O}=f;F(`web:${e}`,S!=null?S:"log",O!=null?O:"");return}if(f.method==="pong"){N.current||D(!0);return}if(f.method==="touchAtTop"){o.emit(!!f.at_top);return}if(f.method==="contextApplied"){N.current&&clearTimeout(N.current),N.current=null,D(!0);return}if(f.method==="ready"){M.current=!0,D(!0);let S=(C=$.getState().instances[e])==null?void 0:C.context;S&&((W=m.current)==null||W.injectJavaScript(Ee(S)));return}try{let S=await at(f,{getHostData:()=>{var O,H;return(H=(O=$.getState().instances[e])==null?void 0:O.host_data)!=null?H:{}},getPermissions:()=>{var O,H;return g?(H=(O=T(g))==null?void 0:O.permissions)!=null?H:[]:[]},is_dark:r,close:Y,app_id:g!=null?g:"",instance_id:e,options:u});f.id&&((j=m.current)==null||j.injectJavaScript(Ge(f.id,S)))}catch(S){if(!f.id)return;let O=S==null?void 0:S.code,H=S instanceof b?S:new b(typeof O=="string"?O:"HOST_ERROR",String((L=S==null?void 0:S.message)!=null?L:S));(Se=m.current)==null||Se.injectJavaScript(Xe(f.id,H))}},[e,r,g,o,u]),Lt=(0,l.useCallback)(()=>{Z(!1),ee(p=>p+1),$e(p=>p+1)},[]);return(0,y.jsxs)(w.View,{style:[w.StyleSheet.absoluteFill,a&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&k.behind],pointerEvents:t?"auto":"none",children:[i?(0,y.jsx)(Tt.default,{ref:m,source:{uri:i.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${i.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:It,onMessage:Dt,bounces:!1,overScrollMode:"never",onLoadStart:p=>{F(`webview:${e}`,"load start",De(p.nativeEvent.url)),M.current=!1,D(!1)},onError:p=>{F(`webview:${e}`,"load error",De(p.nativeEvent.url),p.nativeEvent.description),Z(!0),D(!1)},onLoadEnd:p=>{let f=p.nativeEvent.url;F(`webview:${e}`,"load end",De(f)),g&&(h==null||h({app_id:g,instance_id:e,url:f})),Ne(1500)},onContentProcessDidTerminate:()=>{M.current=!1,D(!1),ee(p=>p+1)},onRenderProcessGone:()=>(M.current=!1,D(!1),ee(p=>p+1),!0),style:k.webview},ie):null,A&&(0,y.jsx)(tn,{visible:!i||!Ot,interactive:V,children:(0,y.jsx)(en,{splash:c,app:A.app,is_dark:r,error:V,has_bundle:!!i,retry:Lt})})]})}),en=l.default.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:s,retry:o})=>{let c=e,u=Me(t.app_id),a=r?"error":!s&&(u==null?void 0:u.status)==="downloading"?"downloading":"loading";return(0,y.jsx)(c,{app:t,is_dark:n,status:a,progress:a==="downloading"?u==null?void 0:u.progress:void 0,retry:o})}),tn=({visible:e,interactive:t,children:n})=>{let r=(0,l.useRef)(new w.Animated.Value(e?1:0)).current,[s,o]=(0,l.useState)(e);return(0,l.useEffect)(()=>{if(e){o(!0),r.setValue(1);return}let c=w.Animated.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return c.start(({finished:u})=>{u&&o(!1)}),()=>c.stop()},[e,r]),s?(0,y.jsx)(w.Animated.View,{style:[w.StyleSheet.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},Le=({app:e,is_dark:t,status:n,progress:r,retry:s})=>{let o=t?"#FAFAFA":"#18181B";return(0,y.jsxs)(w.View,{style:[k.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[(0,y.jsx)(w.View,{style:[k.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?(0,y.jsx)(w.Image,{source:{uri:e.icon},style:k.splash_icon_image}):(0,y.jsx)(w.Text,{style:k.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),(0,y.jsx)(w.Text,{style:[k.splash_name,{color:o}],children:e.name}),n==="error"?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(w.Text,{style:k.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),(0,y.jsx)(w.TouchableOpacity,{activeOpacity:.7,style:[k.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:s,children:(0,y.jsx)(w.Text,{style:[k.retry_text,{color:o}],children:"Th\u1EED l\u1EA1i"})})]}):(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(w.ActivityIndicator,{style:k.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&(0,y.jsxs)(w.Text,{style:k.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},Et=(e,t)=>{let n=(0,l.useRef)(t),r=(0,l.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.`))},nn=({container:e,splash:t=Le,is_dark:n=!1,bridge:r,close_on_back:s=!0,opaque_background:o=!0,onWebLoadEnd:c})=>{Et("container",e),Et("splash",t);let u=e,a=B($,i=>i.active_key),h=(0,l.useRef)(a);a&&(h.current=a);let m=B($,i=>Object.keys(i.instances).join("|")),M=B($,i=>{var x;return i.active_key?(x=i.instances[i.active_key])==null?void 0:x.app.name:void 0}),A=(0,l.useMemo)(()=>m?m.split("|"):[],[m]),[g,I]=(0,l.useState)({}),v=(0,l.useRef)(Xt()).current;(0,l.useEffect)(()=>{if(!a||!s)return;let i=w.BackHandler.addEventListener("hardwareBackPress",()=>(Y(),!0));return()=>i.remove()},[a,s]);let d=(0,l.useCallback)(()=>{let i=$.getState().active_key;i&&I(x=>({...x,[i]:(x[i]||0)+1}))},[]);return A.length?(0,y.jsx)(u,{visible:!!a,title:M!=null?M:"",is_dark:n,close:Y,reload:d,subscribeWebAtTop:v.subscribe,children:A.map(i=>(0,y.jsx)(Zt,{instance_key:i,is_active:a===i,is_front:(a!=null?a:h.current)===i,is_dark:n,reload_tick:g[i]||0,web_at_top:v,splash:t,bridge:r,opaque_background:o,onWebLoadEnd:c},i))}):null},k=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"}}),Rt=l.default.memo(nn);0&&(module.exports={DefaultMiniAppSplash,MINIAPP_PLATFORM_URL,MiniAppHost,MiniAppHostError,closeMiniApp,configureMiniApp,createMmkvStorage,createRnfsFileSystem,ensureMiniApp,getLocalMiniApp,getMiniAppCatalogEntry,getMiniAppStatuses,onMiniAppEvent,openMiniApp,pauseMiniAppDownloads,preloadMiniApp,resumeMiniAppDownloads,sendEventToWeb,syncMiniAppCatalog,uninstallMiniApp,useMiniAppDownload,useMiniAppDownloadsPaused});
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var q=null,Ne=new Set,yt=e=>{q=e,Ne.forEach(t=>t())},v=()=>{if(!q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return q},Be=e=>{Ne.add(e),q&&e()},L=(...e)=>{q!=null&&q.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(o=>o.name)).catch(()=>[]),sha256:n=>e.hash(n,"sha256"),unzip:async(n,r)=>{await t(n,r)},download:({url:n,to_file:r,onProgress:o})=>{let{jobId:a,promise:u}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:c,contentLength:i})=>o==null?void 0:o(c,i)});return{promise:u.then(({statusCode:c})=>({status:c})),cancel:()=>e.stopDownload(a)}}}),vt=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});import Ce,{useCallback as Te,useEffect as N,useMemo as ge,useRef as B,useState as K}from"react";import{ActivityIndicator as Wt,Animated as xe,BackHandler as Ht,Image as jt,StyleSheet as Pe,Text as re,TouchableOpacity as qt,View as Re}from"react-native";import Ut from"react-native-webview";import{Linking as St,Platform as bt}from"react-native";var ae=1,M=class extends Error{constructor(n,r){super(r);this.code=n}},Fe=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===ae&&typeof t.method=="string"?t:null}catch{return null}},pe=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,Ve=(e,t)=>pe({id:e,result:t}),We=(e,t)=>pe({id:e,error:{code:t.code,message:t.message}}),we=e=>pe({event:"context",data:e});var He=()=>`(function () {
1
+ var _e="https://retion-miniapp-platform.vercel.app",q=null,qe=new Set,Rt=e=>{q=e,qe.forEach(t=>t())},S=()=>{if(!q)throw new Error("[miniapp] Ch\u01B0a g\u1ECDi configureMiniApp()");return q},Ue=e=>{qe.add(e),q&&e()},N=(...e)=>{q!=null&&q.debug&&console.log("[miniapp]",...e)};var Pt=(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:c}=e.downloadFile({fromUrl:n,toFile:r,progressInterval:250,begin:()=>{},progress:({bytesWritten:l,contentLength:a})=>s==null?void 0:s(l,a)});return{promise:c.then(({statusCode:l})=>({status:l})),cancel:()=>e.stopDownload(o)}}}),Ct=e=>({getString:t=>e.getString(t),setString:(t,n)=>e.set(t,n)});import Ne,{useCallback as Le,useEffect as F,useMemo as we,useRef as L,useState as Q}from"react";import{ActivityIndicator as Xt,Animated as Ie,BackHandler as Zt,Image as en,StyleSheet as Fe,Text as se,TouchableOpacity as tn,View as $e}from"react-native";import nn from"react-native-webview";import{Linking as Ot,Platform as kt}from"react-native";var le=1,_=class extends Error{constructor(n,r){super(r);this.code=n}},ze=e=>{try{let t=JSON.parse(e);return(t==null?void 0:t.__retion)===le&&typeof t.method=="string"?t:null}catch{return null}},ue=e=>`window.__RETION_MINIAPP__ && window.__RETION_MINIAPP__.receive(${JSON.stringify(e)}); true;`,Qe=(e,t)=>ue({id:e,result:t}),Ye=(e,t)=>ue({id:e,error:{code:t.code,message:t.message}}),be=e=>ue({event:"context",data:e});var Ge=()=>`(function () {
2
2
  var post = function (level, args) {
3
3
  try {
4
4
  var parts = [];
@@ -8,7 +8,7 @@ var q=null,Ne=new Set,yt=e=>{q=e,Ne.forEach(t=>t())},v=()=>{if(!q)throw new Erro
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: ${ae}, method: 'log', level: level, text: parts.join(' ') }));
11
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${le}, 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 q=null,Ne=new Set,yt=e=>{q=e,Ne.forEach(t=>t())},v=()=>{if(!q)throw new Erro
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;`,je=()=>`(function () {
22
+ })(); true;`,Xe=()=>`(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 q=null,Ne=new Set,yt=e=>{q=e,Ne.forEach(t=>t())},v=()=>{if(!q)throw new Erro
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: ${ae}, method: 'touchAtTop', at_top: at_top }));
33
+ window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({ __retion: ${le}, 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 q=null,Ne=new Set,yt=e=>{q=e,Ne.forEach(t=>t())},v=()=>{if(!q)throw new Erro
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;`,qe=e=>pe({event:e}),Ue=(e,t)=>{let n=Ke(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
- ${we(e)}`},Ke=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),ze=(e,t={})=>{let n=Ke(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${ae} };
41
+ })(); true;`,Ze=e=>ue({event:e}),et=(e,t)=>{let n=tt(t);return`try { history.replaceState(history.state, '', location.pathname + ${JSON.stringify(n?`?${n}`:"")} + location.hash); } catch (e) {}
42
+ ${be(e)}`},tt=e=>Object.entries(e).filter(([,t])=>t!=null&&t!=="").map(([t,n])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(n))}`).join("&"),nt=(e,t={})=>{let n=tt(t);return`window.__RETION_MINIAPP_HOST__ = { protocol: ${le} };
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;`},Qe={partner:"partner_token",chatbox:"chatbox_token"},Ye=(e,t)=>{let n={...e};for(let r of Object.values(Qe))t.includes(r)||delete n[r];return n},me=new Set,Je=async(e,t)=>{if(me.has(e))throw new M("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);me.add(e);try{return await t()}finally{me.delete(e)}},Ae=(e,t)=>{if(typeof e!="string"||!e)throw new M("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},Ge=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:o,close:a,app_id:u,instance_id:c,options:i})=>{var _,m,b,p;let g=i==null?void 0:i.handlers,f={app_id:u,instance_id:c,close:a},d=()=>new M("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let l=g==null?void 0:g.requestPayment;if(!l)throw d();let w=t==null?void 0:t.amount;if(typeof w!="number"||!Number.isFinite(w)||w<=0)throw new M("INVALID_PARAMS","amount ph\u1EA3i l\xE0 s\u1ED1 > 0");let E={...t,amount:w,currency:Ae(t==null?void 0:t.currency,"currency")};return Je(e,()=>l(E,f))}case"printImage":{let l=g==null?void 0:g.printImage;if(!l)throw d();let w=Ae(t==null?void 0:t.image,"image");await Je(e,()=>l({image:w},f));return}case"openScreen":if(!(g!=null&&g.openScreen))throw d();await g.openScreen({screen:Ae(t==null?void 0:t.screen,"screen"),params:t==null?void 0:t.params},f);return;case"closeApp":a();return;case"openWebview":{let l=String((_=t==null?void 0:t.url)!=null?_:"");if(!/^https?:\/\//i.test(l))throw new M("INVALID_PARAMS","url ph\u1EA3i l\xE0 http(s)");await(i!=null&&i.openUrl?i.openUrl(l):St.openURL(l));return}case"showToast":(b=i==null?void 0:i.showToast)==null||b.call(i,String((m=t==null?void 0:t.message)!=null?m:""));return;case"getSystemInfo":return{platform:bt.OS==="ios"?"ios":"android",appVersion:(p=i==null?void 0:i.app_version)!=null?p:"",theme:o?"dark":"light"};case"getAccessToken":{let l=n().access_token;if(!l)throw new M("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return l}case"getToken":{let l=t==null?void 0:t.type;if(l==="access"){let W=n().access_token;if(!W)throw new M("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return W}if(l!=="partner"&&l!=="chatbox")throw new M("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(l)}`);let w=Qe[l];if(!r().includes(w))throw new M("PERMISSION_DENIED",`Mini app ch\u01B0a \u0111\u01B0\u1EE3c c\u1EA5p quy\u1EC1n ${w} (Console \u2192 Quy\u1EC1n l\u1EA5y token)`);let E=l==="partner"?n().partner_token:n().chatbox_token;if(!E)throw new M("HOST_ERROR",`Kh\xF4ng c\xF3 ${w}`);return E}case"getUserInfo":{let l=n().user;if(!l)throw new M("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin nh\xE2n vi\xEAn");return l}case"getPageInfo":{let l=n().page;if(!l)throw new M("HOST_ERROR","Kh\xF4ng l\u1EA5y \u0111\u01B0\u1EE3c th\xF4ng tin page");return l}case"sendMessage":case"insertText":throw new M("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF phi\xEAn b\u1EA3n app n\xE0y`);default:throw new M("NOT_SUPPORTED",`API kh\xF4ng t\u1ED3n t\u1EA1i: ${e}`)}};var et=e=>`bundle:${e}`,tt=()=>`${v().file_system.document_dir}/miniapps`,nt=(e,t,n="index.html",r=!1,o=[])=>{let a=`${tt()}/${e}/${t}`;return{app_id:e,version:t,dir:a,entry_uri:`file://${a}/${n}`,context_update:r,permissions:o}},Xe=e=>{var t;v().storage.setString(et(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},xt=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,S=e=>{let t=v().storage.getString(et(e));if(!t)return null;try{let{version:n,entry:r,context_update:o,permissions:a}=JSON.parse(t);return nt(e,n,r,!!o,Array.isArray(a)?a:[])}catch{return null}},le=e=>v().file_system.exists(e.entry_uri.replace("file://","")),Me=async e=>{let t=S(e.app_id);return(t==null?void 0:t.version)===e.version&&await le(t)},Et=async(e,t)=>{let n=v().file_system,r=`${tt()}/${e}`,o=await n.listDir(r).catch(()=>[]);await Promise.all(o.filter(a=>!t.includes(a)).map(a=>n.remove(`${r}/${a}`).catch(()=>{})))},z=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},ce={},ye=(e,{base_url:t,onProgress:n}={})=>{var _;let r=v().file_system,o=null,a=!1,u=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,c=()=>{if(a)throw new z},i=async()=>{var p;c();let m=S(e.app_id);if((m==null?void 0:m.version)===e.version&&await r.exists(m.dir))return Xe(e),S(e.app_id);c();let b=r.download({url:t?xt(t,e.bundle_url):e.bundle_url,to_file:u,onProgress:(l,w)=>{var W;let E=w>0?w:(W=e.size)!=null?W:0;E>0&&(n==null||n(Math.min(1,l/E)))}});o=b;try{let{status:l}=await b.promise;if(c(),l!==200)throw new Error(`bundle ${l}`);if(e.sha256)if(r.sha256){if(await r.sha256(u)!==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);c();let w=nt(e.app_id,e.version,e.entry,!!e.context_update,(p=e.permissions)!=null?p:[]);return await r.remove(w.dir).catch(()=>{}),await r.mkdir(w.dir),await r.unzip(u,w.dir),Xe(e),Et(e.app_id,[e.version,m==null?void 0:m.version].filter(Boolean)),w}catch(l){throw a?new z:l}finally{o=null,r.remove(u).catch(()=>{})}},f=((_=ce[e.app_id])!=null?_:Promise.resolve()).catch(()=>{}).then(i),d=f.catch(()=>{});return ce[e.app_id]=d,d.then(()=>{ce[e.app_id]===d&&delete ce[e.app_id]}),{promise:f,cancel:()=>{a=!0,o==null||o.cancel()}}},ee={},Tt=__DEV__?0:60*1e3,Ze={},rt=(e,t)=>{var r,o;let n=S(e);return n&&Date.now()-((r=Ze[t])!=null?r:0)<Tt?Promise.resolve(n):((o=ee[e])!=null||(ee[e]=(async()=>{let a=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!a.ok)throw new Error(`manifest ${a.status}`);let u=await a.json(),c=await ye(u,{base_url:t}).promise;return Ze[t]=Date.now(),c})().catch(a=>(console.warn("[miniapp] sync failed",e,a==null?void 0:a.message),S(e))).finally(()=>{ee[e]=void 0})),ee[e])};var ue=new Map,ot=(e,t)=>(ue.set(e,t),()=>{ue.get(e)===t&&ue.delete(e)}),Rt=(e,t)=>{let n=ue.get(e);return n?n(t):!1};import{useRef as Ct,useSyncExternalStore as Pt}from"react";var de=e=>{let t=e,n=new Set;return{getState:()=>t,setState:r=>{let o=typeof r=="function"?r(t):r;t={...t,...o},n.forEach(a=>a())},subscribe:r=>(n.add(r),()=>{n.delete(r)})}},J=(e,t,n=Object.is)=>{let r=Ct(null),o=()=>{let a=e.getState(),u=r.current;if(u&&u.state===a&&u.selector===t)return u.value;let c=t(a),i=u&&n(u.value,c)?u.value:c;return r.current={state:a,selector:t,value:i},i};return Pt(e.subscribe,o)};var D=de({active_key:null,instances:{}}),it=({app:e,instance_id:t,context:n={},url_params:r={},host_data:o={}},a)=>{var c;let u=(c=v().keep_alive)==null?void 0:c.max_webviews;D.setState(i=>{let g=t!=null?t:e.app_id,f={...i.instances,[g]:{key:g,app:e,context:n,url_params:r,host_data:o,last_used_at:Date.now()}},d=Object.keys(f);return u&&u>0&&d.length>u&&d.filter(_=>_!==g).sort((_,m)=>f[_].last_used_at-f[m].last_used_at).slice(0,d.length-u).forEach(_=>{delete f[_]}),a?{active_key:g,instances:f}:{instances:f}})},Ot=e=>it(e,!0),kt=e=>it(e,!1),te=()=>D.setState({active_key:null}),st=e=>{D.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var at="catalog",Dt=10*1e3,It=2,$t=3e3,Lt=()=>{var e;try{return JSON.parse((e=v().storage.getString(at))!=null?e:"{}")}catch{return{}}},T=de({catalog:{},downloads:{},pause_reasons:[]});Be(()=>T.setState({catalog:Lt()}));var ve=e=>J(T,t=>e?t.downloads[e]:void 0),Nt=()=>J(T,e=>e.pause_reasons.length>0),Y=(...e)=>L("queue",...e),I=[],Q={},y=null,U={},V=(e,t)=>{T.setState(n=>{let r=n.downloads[e];return{downloads:{...n.downloads,[e]:{...r!=null?r:{status:"queued",progress:0},...t}}}})},_e=(e,t)=>{var n;(n=U[e])==null||n.forEach(r=>r(t)),delete U[e]},Bt=()=>T.getState().pause_reasons.length>0,G=e=>{var c;if(y)return;let t=e?I.indexOf(e):Bt()?-1:0;if(t<0||t>=I.length)return;let[n]=I.splice(t,1),r=T.getState().catalog[n];if(!r){_e(n,S(n)),G();return}let o=Date.now();Q[n]=((c=Q[n])!=null?c:0)+1,V(n,{status:"downloading",progress:0,version:r.version,error:void 0});let a=0,u=ye(r,{onProgress:i=>{let g=Math.floor(i*100);g!==a&&(a=g,V(n,{progress:g/100,version:r.version}))}});y={app_id:n,handle:u,forced:!!e},Y("start",n,r.version,e?"(forced)":""),u.promise.then(i=>{Y("installed",n,r.version,`${Date.now()-o}ms`),V(n,{status:"installed",progress:1,version:r.version}),_e(n,i)}).catch(i=>{var f;if(i instanceof z){Y("paused",n),Q[n]-=1,I.unshift(n),V(n,{status:"queued",progress:0,version:r.version});return}let g=String((f=i==null?void 0:i.message)!=null?f:i);if(console.warn("[miniapp-queue] failed",n,g),Q[n]<It){V(n,{status:"queued",progress:0,version:r.version,error:g}),setTimeout(()=>{var d;I.includes(n)||(y==null?void 0:y.app_id)===n||(I.push(n),G((d=U[n])!=null&&d.length?n:void 0))},$t);return}V(n,{status:"failed",progress:0,version:r.version,error:g}),_e(n,S(n))}).finally(()=>{y=null;let i=I.find(g=>{var f;return(f=U[g])==null?void 0:f.length});G(i)})},pt=(e,{front:t=!1}={})=>{if((y==null?void 0:y.app_id)===e)return;let n=I.indexOf(e);if(n>=0){if(!t)return;I.splice(n,1)}t?I.unshift(e):I.push(e)},Jt=async e=>{let{platform_url:t,host_id:n,client_token:r}=v(),o=new AbortController,a=setTimeout(()=>o.abort(),Dt);try{let u=`${t}/api/hosts/${encodeURIComponent(n)}/miniapps?channel=${e}`,c=await fetch(u,{headers:{Authorization:`Bearer ${r}`,"Cache-Control":"no-cache"},signal:o.signal});if(!c.ok)throw new Error(`host list ${e} ${c.status}`);return(await c.json()).apps.map(g=>({...g,channel:e}))}finally{clearTimeout(a)}},ne=null,Se=()=>(ne!=null||(ne=(async()=>{let e=Date.now();try{let t=await Promise.all(v().channels.map(Jt)),n={};[...t].reverse().flat().forEach(o=>{n[o.app_id]=o}),v().storage.setString(at,JSON.stringify(n)),T.setState({catalog:n});let r=[];for(let o of Object.values(n))await Me(o)?V(o.app_id,{status:"installed",progress:1,version:o.version}):r.push(o);r.forEach(o=>{Q[o.app_id]=0,V(o.app_id,{status:"queued",progress:0,version:o.version,error:void 0}),pt(o.app_id)}),Y("catalog",Object.keys(n).length,"apps, outdated",r.map(o=>o.app_id),`${Date.now()-e}ms`),G()}catch(t){console.warn("[miniapp-queue] sync catalog failed",t==null?void 0:t.message)}finally{ne=null}})()),ne),Ft=e=>{let{pause_reasons:t}=T.getState();t.includes(e)||(T.setState({pause_reasons:[...t,e]}),Y("pause",e),y&&!y.forced&&y.handle.cancel())},Vt=e=>{let{pause_reasons:t}=T.getState();t.includes(e)&&(T.setState({pause_reasons:t.filter(n=>n!==e)}),Y("resume",e),G())},ct=e=>T.getState().catalog[e],be=async e=>{let t=ct(e);if(!t)return;if(await Me(t))return S(e);let n=new Promise(r=>{var o;((o=U[e])!=null?o:U[e]=[]).push(r)});return(y==null?void 0:y.app_id)===e?y.forced=!0:(Q[e]=0,pt(e,{front:!0}),y&&!y.forced?y.handle.cancel():G(e)),n};import{Fragment as dt,jsx as x,jsxs as oe}from"react/jsx-runtime";var Ee=e=>(e!=null?e:"").replace(/\?[^#]*/,""),lt=0,Kt=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},zt=Ce.memo(({instance_key:e,is_active:t,is_dark:n,reload_tick:r,web_at_top:o,splash:a,bridge:u,onWebLoadEnd:c})=>{var $e,Le;let i=B(null),g=B(!1),f=J(D,s=>s.instances[e]),d=f==null?void 0:f.app.app_id,_=f==null?void 0:f.app.manifest_url,m=f==null?void 0:f.context,b=f==null?void 0:f.url_params,[p,l]=K(()=>d?S(d):null),[w,E]=K(!1),[W,Oe]=K(0),[ft,X]=K(0),[ht,O]=K(!1),$=B(null),ke=s=>{$.current&&clearTimeout($.current),$.current=setTimeout(()=>{$.current=null,O(!0)},s)};N(()=>()=>{$.current&&clearTimeout($.current)},[]),N(()=>{if(!d||!t&&p)return;let s=!0;return E(!1),(async()=>{let h=S(d),R=h?await le(h):!1;if(!s||(l(R?k=>!k||k.version!==h.version||k.permissions.join(",")!==h.permissions.join(",")?h:k:null),__DEV__&&Date.now()-lt>1e4&&(lt=Date.now(),await Se()),!s))return;let F=await be(d),H=F!==void 0?F:_?await rt(d,_):S(d);if(s){if(!H){E(!0);return}l(k=>k!=null?k:H)}})(),()=>{s=!1}},[t,d,_,W]),N(()=>ot(e,s=>i.current?(i.current.postMessage(s),!0):!1),[e]);let mt=J(T,s=>{let h=d?s.downloads[d]:void 0;return(h==null?void 0:h.status)==="installed"?h.version:void 0});N(()=>{if(t||!d||!p)return;let s=S(d);if(!s||s.version===p.version)return;let h=!0;return le(s).then(R=>{!h||!R||(L(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",p.version,"\u2192",s.version),l(s))}),()=>{h=!1}},[t,d,mt,p==null?void 0:p.version]),N(()=>{var R;let s=(R=v().keep_alive)==null?void 0:R.idle_close_ms;if(t||!s||s<=0)return;let h=setTimeout(()=>{st(e)},s);return()=>clearTimeout(h)},[t,e]),N(()=>{r>0&&(E(!1),O(!1),X(s=>s+1),Oe(s=>s+1))},[r]);let De=B(t);N(()=>{var s;De.current!==t&&(De.current=t,g.current&&((s=i.current)==null||s.injectJavaScript(qe(t?"resumed":"paused"))))},[t]);let ie=`${($e=p==null?void 0:p.version)!=null?$e:"none"}:${(Le=p==null?void 0:p.permissions.join(","))!=null?Le:""}:${ft}`,Z=ge(()=>JSON.stringify([m!=null?m:{},b!=null?b:{}]),[m,b]),fe=ge(()=>{var s;return Ye(b!=null?b:{},(s=p==null?void 0:p.permissions)!=null?s:[])},[Z,p==null?void 0:p.permissions]),At=ge(()=>ze(m!=null?m:{},fe)+je()+(v().debug?He():""),[fe]),se=B(null),Ie=B(null);N(()=>{var h,R,F;if(!p)return;if(Ie.current!==ie){Ie.current=ie,se.current=Z;return}if(se.current===Z)return;let s=((R=JSON.parse((h=se.current)!=null?h:"[]")[0])!=null?R:{}).org_id;if(se.current=Z,s===(m==null?void 0:m.org_id)&&g.current){O(!1),ke(1500),(F=i.current)==null||F.injectJavaScript(Ue(m!=null?m:{},fe));return}O(!1),X(H=>H+1)},[Z,p,ie]);let wt=Te(async s=>{var R,F,H,k,he;let h=Fe(s.nativeEvent.data);if(!h){if(d&&(u!=null&&u.onWebEvent))try{Promise.resolve(u.onWebEvent(s.nativeEvent.data,{app_id:d,instance_id:e})).catch(A=>{console.warn("[miniapp] onWebEvent l\u1ED7i",d,A)})}catch(A){console.warn("[miniapp] onWebEvent l\u1ED7i",d,A)}return}if(h.method==="log"){let{level:A,text:C}=h;L(`web:${e}`,A!=null?A:"log",C!=null?C:"");return}if(h.method==="pong"){$.current||O(!0);return}if(h.method==="touchAtTop"){o.emit(!!h.at_top);return}if(h.method==="contextApplied"){$.current&&clearTimeout($.current),$.current=null,O(!0);return}if(h.method==="ready"){g.current=!0,O(!0);let A=(R=D.getState().instances[e])==null?void 0:R.context;A&&((F=i.current)==null||F.injectJavaScript(we(A)));return}try{let A=await Ge(h,{getHostData:()=>{var C,j;return(j=(C=D.getState().instances[e])==null?void 0:C.host_data)!=null?j:{}},getPermissions:()=>{var C,j;return d?(j=(C=S(d))==null?void 0:C.permissions)!=null?j:[]:[]},is_dark:n,close:te,app_id:d!=null?d:"",instance_id:e,options:u});h.id&&((H=i.current)==null||H.injectJavaScript(Ve(h.id,A)))}catch(A){if(!h.id)return;let C=A==null?void 0:A.code,j=A instanceof M?A:new M(typeof C=="string"?C:"HOST_ERROR",String((k=A==null?void 0:A.message)!=null?k:A));(he=i.current)==null||he.injectJavaScript(We(h.id,j))}},[e,n,d,o,u]),Mt=Te(()=>{E(!1),X(s=>s+1),Oe(s=>s+1)},[]);return oe(Re,{style:[Pe.absoluteFill,!t&&P.behind],pointerEvents:t?"auto":"none",children:[p?x(Ut,{ref:i,source:{uri:p.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${p.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:At,onMessage:wt,bounces:!1,overScrollMode:"never",onLoadStart:s=>{L(`webview:${e}`,"load start",Ee(s.nativeEvent.url)),g.current=!1,O(!1)},onError:s=>{L(`webview:${e}`,"load error",Ee(s.nativeEvent.url),s.nativeEvent.description),E(!0),O(!1)},onLoadEnd:s=>{let h=s.nativeEvent.url;L(`webview:${e}`,"load end",Ee(h)),d&&(c==null||c({app_id:d,instance_id:e,url:h})),ke(1500)},onContentProcessDidTerminate:()=>{g.current=!1,O(!1),X(s=>s+1)},onRenderProcessGone:()=>(g.current=!1,O(!1),X(s=>s+1),!0),style:P.webview},ie):null,f&&x(Yt,{visible:!p||!ht,interactive:w,children:x(Qt,{splash:a,app:f.app,is_dark:n,error:w,has_bundle:!!p,retry:Mt})})]})}),Qt=Ce.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:o,retry:a})=>{let u=e,c=ve(t.app_id),i=r?"error":!o&&(c==null?void 0:c.status)==="downloading"?"downloading":"loading";return x(u,{app:t,is_dark:n,status:i,progress:i==="downloading"?c==null?void 0:c.progress:void 0,retry:a})}),Yt=({visible:e,interactive:t,children:n})=>{let r=B(new xe.Value(e?1:0)).current,[o,a]=K(e);return N(()=>{if(e){a(!0),r.setValue(1);return}let u=xe.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return u.start(({finished:c})=>{c&&a(!1)}),()=>u.stop()},[e,r]),o?x(xe.View,{style:[Pe.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},gt=({app:e,is_dark:t,status:n,progress:r,retry:o})=>{let a=t?"#FAFAFA":"#18181B";return oe(Re,{style:[P.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[x(Re,{style:[P.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?x(jt,{source:{uri:e.icon},style:P.splash_icon_image}):x(re,{style:P.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),x(re,{style:[P.splash_name,{color:a}],children:e.name}),n==="error"?oe(dt,{children:[x(re,{style:P.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),x(qt,{activeOpacity:.7,style:[P.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:o,children:x(re,{style:[P.retry_text,{color:a}],children:"Th\u1EED l\u1EA1i"})})]}):oe(dt,{children:[x(Wt,{style:P.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&oe(re,{style:P.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},ut=(e,t)=>{let n=B(t),r=B(!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.`))},Gt=({container:e,splash:t=gt,is_dark:n=!1,bridge:r,close_on_back:o=!0,onWebLoadEnd:a})=>{ut("container",e),ut("splash",t);let u=e,c=J(D,p=>p.active_key),i=J(D,p=>Object.keys(p.instances).join("|")),g=J(D,p=>{var l;return p.active_key?(l=p.instances[p.active_key])==null?void 0:l.app.name:void 0}),f=ge(()=>i?i.split("|"):[],[i]),[d,_]=K({}),m=B(Kt()).current;N(()=>{if(!c||!o)return;let p=Ht.addEventListener("hardwareBackPress",()=>(te(),!0));return()=>p.remove()},[c,o]);let b=Te(()=>{let p=D.getState().active_key;p&&_(l=>({...l,[p]:(l[p]||0)+1}))},[]);return f.length?x(u,{visible:!!c,title:g!=null?g:"",is_dark:n,close:te,reload:b,subscribeWebAtTop:m.subscribe,children:f.map(p=>x(zt,{instance_key:p,is_active:c===p,is_dark:n,reload_tick:d[p]||0,web_at_top:m,splash:t,bridge:r,onWebLoadEnd:a},p))}):null},P=Pe.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"}}),Xt=Ce.memo(Gt);export{gt as DefaultMiniAppSplash,Xt as MiniAppHost,M as MiniAppHostError,te as closeMiniApp,yt as configureMiniApp,vt as createMmkvStorage,_t as createRnfsFileSystem,be as ensureMiniApp,S as getLocalMiniApp,ct as getMiniAppCatalogEntry,Ot as openMiniApp,Ft as pauseMiniAppDownloads,kt as preloadMiniApp,Vt as resumeMiniAppDownloads,Rt as sendEventToWeb,Se as syncMiniAppCatalog,ve as useMiniAppDownload,Nt as useMiniAppDownloadsPaused};
45
+ true;`},rt={partner:"partner_token",chatbox:"chatbox_token"},ot=(e,t)=>{let n={...e};for(let r of Object.values(rt))t.includes(r)||delete n[r];return n},ve=new Set,Ke=async(e,t)=>{if(ve.has(e))throw new _("BUSY",`${e} \u0111ang ch\u1EA1y \u2014 ch\u1EDD l\u01B0\u1EE3t tr\u01B0\u1EDBc xong`);ve.add(e);try{return await t()}finally{ve.delete(e)}},Se=(e,t)=>{if(typeof e!="string"||!e)throw new _("INVALID_PARAMS",`Thi\u1EBFu ${t}`);return e},it=async({method:e,params:t},{getHostData:n,getPermissions:r,is_dark:s,close:o,app_id:c,instance_id:l,options:a})=>{var m,d,O,M;let f=a==null?void 0:a.handlers,h={app_id:c,instance_id:l,close:o},A=()=>new _("NOT_SUPPORTED",`${e} ch\u01B0a h\u1ED7 tr\u1EE3 \u1EDF \u1EE9ng d\u1EE5ng n\xE0y`);switch(e){case"requestPayment":{let u=f==null?void 0:f.requestPayment;if(!u)throw A();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 v={...t,amount:i,currency:Se(t==null?void 0:t.currency,"currency")};return Ke(e,()=>u(v,h))}case"printImage":{let u=f==null?void 0:f.printImage;if(!u)throw A();let i=Se(t==null?void 0:t.image,"image");await Ke(e,()=>u({image:i},h));return}case"openScreen":if(!(f!=null&&f.openScreen))throw A();await f.openScreen({screen:Se(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(a!=null&&a.openUrl?a.openUrl(u):Ot.openURL(u));return}case"showToast":(O=a==null?void 0:a.showToast)==null||O.call(a,String((d=t==null?void 0:t.message)!=null?d:""));return;case"getSystemInfo":return{platform:kt.OS==="ios"?"ios":"android",appVersion:(M=a==null?void 0:a.app_version)!=null?M:"",theme:s?"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 V=n().access_token;if(!V)throw new _("HOST_ERROR","Mini app ch\u01B0a c\xF3 token cho page n\xE0y");return V}if(u!=="partner"&&u!=="chatbox")throw new _("HOST_ERROR",`Lo\u1EA1i token kh\xF4ng h\u1EE3p l\u1EC7: ${String(u)}`);let i=rt[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 v=u==="partner"?n().partner_token:n().chatbox_token;if(!v)throw new _("HOST_ERROR",`Kh\xF4ng c\xF3 ${i}`);return v}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 xe=e=>`bundle:${e}`,Ee=()=>`${S().file_system.document_dir}/miniapps`,pt=(e,t,n="index.html",r=!1,s=[])=>{let o=`${Ee()}/${e}/${t}`;return{app_id:e,version:t,dir:o,entry_uri:`file://${o}/${n}`,context_update:r,permissions:s}},st=e=>{var t;S().storage.setString(xe(e.app_id),JSON.stringify({version:e.version,entry:e.entry,context_update:!!e.context_update,permissions:(t=e.permissions)!=null?t:[]}))},It=(e,t)=>/^https?:\/\//.test(t)?t:`${e.replace(/[^/]*$/,"")}${t}`,x=e=>{let t=S().storage.getString(xe(e));if(!t)return null;try{let{version:n,entry:r,context_update:s,permissions:o}=JSON.parse(t);return pt(e,n,r,!!s,Array.isArray(o)?o:[])}catch{return null}},de=e=>S().file_system.exists(e.entry_uri.replace("file://","")),Te=async e=>{let t=x(e.app_id);return(t==null?void 0:t.version)===e.version&&await de(t)},Dt=async(e,t)=>{let n=S().file_system,r=`${Ee()}/${e}`,s=await n.listDir(r).catch(()=>[]);await Promise.all(s.filter(o=>!t.includes(o)).map(o=>n.remove(`${r}/${o}`).catch(()=>{})))},ct=async e=>{var t;await((t=re[e])==null?void 0:t.catch(()=>{})),S().storage.setString(xe(e),""),await S().file_system.remove(`${Ee()}/${e}`).catch(()=>{})},Y=class extends Error{constructor(){super("cancelled"),this.name="MiniAppInstallCancelled"}},re={},Re=(e,{base_url:t,onProgress:n}={})=>{var m;let r=S().file_system,s=null,o=!1,c=`${r.cache_dir}/${e.app_id}-${e.version}.zip`,l=()=>{if(o)throw new Y},a=async()=>{var M;l();let d=x(e.app_id);if((d==null?void 0:d.version)===e.version&&await r.exists(d.dir))return st(e),x(e.app_id);l();let O=r.download({url:t?It(t,e.bundle_url):e.bundle_url,to_file:c,onProgress:(u,i)=>{var V;let v=i>0?i:(V=e.size)!=null?V:0;v>0&&(n==null||n(Math.min(1,u/v)))}});s=O;try{let{status:u}=await O.promise;if(l(),u!==200)throw new Error(`bundle ${u}`);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=pt(e.app_id,e.version,e.entry,!!e.context_update,(M=e.permissions)!=null?M:[]);return await r.remove(i.dir).catch(()=>{}),await r.mkdir(i.dir),await r.unzip(c,i.dir),st(e),Dt(e.app_id,[e.version,d==null?void 0:d.version].filter(Boolean)),i}catch(u){throw o?new Y:u}finally{s=null,r.remove(c).catch(()=>{})}},h=((m=re[e.app_id])!=null?m:Promise.resolve()).catch(()=>{}).then(a),A=h.catch(()=>{});return re[e.app_id]=A,A.then(()=>{re[e.app_id]===A&&delete re[e.app_id]}),{promise:h,cancel:()=>{o=!0,s==null||s.cancel()}}},ne={},Lt=__DEV__?0:60*1e3,at={},lt=(e,t)=>{var r,s;let n=x(e);return n&&Date.now()-((r=at[t])!=null?r:0)<Lt?Promise.resolve(n):((s=ne[e])!=null||(ne[e]=(async()=>{let o=await fetch(t,{headers:{"Cache-Control":"no-cache"}});if(!o.ok)throw new Error(`manifest ${o.status}`);let c=await o.json(),l=await Re(c,{base_url:t}).promise;return at[t]=Date.now(),l})().catch(o=>(console.warn("[miniapp] sync failed",e,o==null?void 0:o.message),x(e))).finally(()=>{ne[e]=void 0})),ne[e])};var ge=new Map,ut=(e,t)=>(ge.set(e,t),()=>{ge.get(e)===t&&ge.delete(e)}),$t=(e,t)=>{let n=ge.get(e);return n?n(t):!1};import{useRef as Nt,useSyncExternalStore as Ft}from"react";var fe=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)})}},B=(e,t,n=Object.is)=>{let r=Nt(null),s=()=>{let o=e.getState(),c=r.current;if(c&&c.state===o&&c.selector===t)return c.value;let l=t(o),a=c&&n(c.value,l)?c.value:l;return r.current={state:o,selector:t,value:a},a};return Ft(e.subscribe,s)};var D=fe({active_key:null,instances:{}}),dt=({app:e,instance_id:t,context:n={},url_params:r={},host_data:s={}},o)=>{var l;let c=(l=S().keep_alive)==null?void 0:l.max_webviews;D.setState(a=>{let f=t!=null?t:e.app_id,h={...a.instances,[f]:{key:f,app:e,context:n,url_params:r,host_data:s,last_used_at:Date.now()}},A=Object.keys(h);return c&&c>0&&A.length>c&&A.filter(m=>m!==f).sort((m,d)=>h[m].last_used_at-h[d].last_used_at).slice(0,A.length-c).forEach(m=>{delete h[m]}),o?{active_key:f,instances:h}:{instances:h}})},Bt=e=>dt(e,!0),Jt=e=>dt(e,!1),oe=()=>D.setState({active_key:null}),he=e=>{D.setState(t=>{if(t.active_key===e||!t.instances[e])return{};let n={...t.instances};return delete n[e],{instances:n}})};var gt="catalog",Vt=10*1e3,Wt=2,jt=3e3,Ht=()=>{var e;try{return JSON.parse((e=S().storage.getString(gt))!=null?e:"{}")}catch{return{}}},b=fe({catalog:{},downloads:{},pause_reasons:[]});Ue(()=>b.setState({catalog:Ht()}));var Ce=e=>B(b,t=>e?t.downloads[e]:void 0),qt=()=>B(b,e=>e.pause_reasons.length>0),K=(...e)=>N("queue",...e),T=[],U={},w=null,me=new Set,z={},Pe=new Set,X=e=>{Pe.forEach(t=>{try{t(e)}catch(n){console.warn("[miniapp-queue] event listener error",n==null?void 0:n.message)}})},Ut=e=>(Pe.add(e),()=>{Pe.delete(e)}),Kt=()=>b.getState().downloads,J=(e,t)=>{let n=!!x(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(c=>({downloads:{...c.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})},Ae=(e,t)=>{var n;(n=z[e])==null||n.forEach(r=>r(t)),delete z[e]},zt=()=>b.getState().pause_reasons.length>0,G=e=>{var l;if(w)return;let t=e?T.indexOf(e):zt()?-1:0;if(t<0||t>=T.length)return;let[n]=T.splice(t,1),r=b.getState().catalog[n];if(!r){Ae(n,x(n)),G();return}let s=Date.now();U[n]=((l=U[n])!=null?l:0)+1,J(n,{status:"downloading",progress:0,version:r.version,error:void 0});let o=0,c=Re(r,{onProgress:a=>{let f=Math.floor(a*100);f!==o&&(o=f,J(n,{progress:f/100,version:r.version}))}});w={app_id:n,handle:c,forced:!!e},K("start",n,r.version,e?"(forced)":""),c.promise.then(a=>{K("installed",n,r.version,`${Date.now()-s}ms`),J(n,{status:"installed",progress:1,version:r.version}),Ae(n,a)}).catch(a=>{var h;if(a instanceof Y){if(me.has(n))return;K("paused",n),U[n]-=1,T.unshift(n),J(n,{status:"queued",progress:0,version:r.version});return}let f=String((h=a==null?void 0:a.message)!=null?h:a);if(console.warn("[miniapp-queue] failed",n,f),U[n]<Wt){J(n,{status:"queued",progress:0,version:r.version,error:f}),setTimeout(()=>{var A;T.includes(n)||(w==null?void 0:w.app_id)===n||(T.push(n),G((A=z[n])!=null&&A.length?n:void 0))},jt);return}J(n,{status:"failed",progress:0,version:r.version,error:f}),Ae(n,x(n))}).finally(()=>{w=null;let a=T.find(f=>{var h;return(h=z[f])==null?void 0:h.length});G(a)})},ft=(e,{front:t=!1}={})=>{if((w==null?void 0:w.app_id)===e)return;let n=T.indexOf(e);if(n>=0){if(!t)return;T.splice(n,1)}t?T.unshift(e):T.push(e)},Qt=async e=>{let{host_id:t,client_token:n}=S(),r=new AbortController,s=setTimeout(()=>r.abort(),Vt);try{let o=`${_e}/api/hosts/${encodeURIComponent(t)}/miniapps?channel=${e}`,c=await fetch(o,{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(a=>({...a,channel:e}))}finally{clearTimeout(s)}},ie=null,Oe=()=>(ie!=null||(ie=(async()=>{let e=Date.now();try{let t=await Promise.all(S().channels.map(Qt)),n={};[...t].reverse().flat().forEach(o=>{n[o.app_id]=o});let r=Object.keys(b.getState().catalog).filter(o=>!n[o]);S().storage.setString(gt,JSON.stringify(n)),b.setState({catalog:n}),await Promise.all(r.map(ht));let s=[];for(let o of Object.values(n))await Te(o)?J(o.app_id,{status:"installed",progress:1,version:o.version}):s.push(o);s.forEach(o=>{U[o.app_id]=0,J(o.app_id,{status:"queued",progress:0,version:o.version,error:void 0}),ft(o.app_id)}),K("catalog",Object.keys(n).length,"apps, outdated",s.map(o=>o.app_id),"removed",r,`${Date.now()-e}ms`),X({type:"sync_complete",app_ids:Object.keys(n),removed:r}),G()}catch(t){console.warn("[miniapp-queue] sync catalog failed",t==null?void 0:t.message)}finally{ie=null}})()),ie),ht=async e=>{var r,s,o,c;if(me.has(e))return;me.add(e);let t=T.indexOf(e);t>=0&&T.splice(t,1),(w==null?void 0:w.app_id)===e&&w.handle.cancel();let n=(c=(o=(r=b.getState().downloads[e])==null?void 0:r.version)!=null?o:(s=x(e))==null?void 0:s.version)!=null?c:"";J(e,{status:"uninstalling",progress:0,version:n}),await ct(e),he(e),b.setState(l=>{let a={...l.downloads};return delete a[e],{downloads:a}}),delete U[e],me.delete(e),Ae(e,null),K("uninstalled",e),X({type:"uninstalled",app_id:e})},Yt=e=>{let{pause_reasons:t}=b.getState();t.includes(e)||(b.setState({pause_reasons:[...t,e]}),K("pause",e),t.length===0&&X({type:"pause_change",paused:!0,reasons:[e]}),w&&!w.forced&&w.handle.cancel())},Gt=e=>{let{pause_reasons:t}=b.getState();if(!t.includes(e))return;let n=t.filter(r=>r!==e);b.setState({pause_reasons:n}),K("resume",e),n.length===0&&X({type:"pause_change",paused:!1,reasons:n}),G()},mt=e=>b.getState().catalog[e],ke=async e=>{let t=mt(e);if(!t)return;if(await Te(t))return x(e);let n=new Promise(r=>{var s;((s=z[e])!=null?s:z[e]=[]).push(r)});return(w==null?void 0:w.app_id)===e?w.forced=!0:(U[e]=0,ft(e,{front:!0}),w&&!w.forced?w.handle.cancel():G(e)),n};import{Fragment as Mt,jsx as E,jsxs as ae}from"react/jsx-runtime";var De=e=>(e!=null?e:"").replace(/\?[^#]*/,""),At=0,rn=()=>{let e=new Set;return{emit:t=>e.forEach(n=>n(t)),subscribe:t=>(e.add(t),()=>{e.delete(t)})}},on=Ne.memo(({instance_key:e,is_active:t,is_front:n,is_dark:r,reload_tick:s,web_at_top:o,splash:c,bridge:l,opaque_background:a,onWebLoadEnd:f})=>{var je,He;let h=L(null),A=L(!1),m=B(D,p=>p.instances[e]),d=m==null?void 0:m.app.app_id,O=m==null?void 0:m.app.manifest_url,M=m==null?void 0:m.context,u=m==null?void 0:m.url_params,[i,v]=Q(()=>d?x(d):null),[V,Z]=Q(!1),[_t,Be]=Q(0),[vt,ee]=Q(0),[St,k]=Q(!1),$=L(null),Je=p=>{$.current&&clearTimeout($.current),$.current=setTimeout(()=>{$.current=null,k(!0)},p)};F(()=>()=>{$.current&&clearTimeout($.current)},[]),F(()=>{if(!d||!t&&i)return;let p=!0;return Z(!1),(async()=>{let g=x(d),R=g?await de(g):!1;if(!p||(v(R?I=>!I||I.version!==g.version||I.permissions.join(",")!==g.permissions.join(",")?g:I:null),__DEV__&&Date.now()-At>1e4&&(At=Date.now(),await Oe()),!p))return;let W=await ke(d),j=W!==void 0?W:O?await lt(d,O):x(d);if(p){if(!j){Z(!0);return}v(I=>I!=null?I:j)}})(),()=>{p=!1}},[t,d,O,_t]),F(()=>ut(e,p=>h.current?(h.current.postMessage(p),!0):!1),[e]);let bt=B(b,p=>{let g=d?p.downloads[d]:void 0;return(g==null?void 0:g.status)==="installed"?g.version:void 0});F(()=>{if(t||!d||!i)return;let p=x(d);if(!p||p.version===i.version)return;let g=!0;return de(p).then(R=>{!g||!R||(N(`webview:${e}`,"\u0111\u1ED5i bundle (\u1EA9n)",i.version,"\u2192",p.version),v(p))}),()=>{g=!1}},[t,d,bt,i==null?void 0:i.version]),F(()=>{var R;let p=(R=S().keep_alive)==null?void 0:R.idle_close_ms;if(t||!p||p<=0)return;let g=setTimeout(()=>{he(e)},p);return()=>clearTimeout(g)},[t,e]),F(()=>{s>0&&(Z(!1),k(!1),ee(p=>p+1),Be(p=>p+1))},[s]);let Ve=L(t);F(()=>{var p;Ve.current!==t&&(Ve.current=t,A.current&&((p=h.current)==null||p.injectJavaScript(Ze(t?"resumed":"paused"))))},[t]);let pe=`${(je=i==null?void 0:i.version)!=null?je:"none"}:${(He=i==null?void 0:i.permissions.join(","))!=null?He:""}:${vt}`,te=we(()=>JSON.stringify([M!=null?M:{},u!=null?u:{}]),[M,u]),Me=we(()=>{var p;return ot(u!=null?u:{},(p=i==null?void 0:i.permissions)!=null?p:[])},[te,i==null?void 0:i.permissions]),xt=we(()=>nt(M!=null?M:{},Me)+Xe()+(S().debug?Ge():""),[Me]),ce=L(null),We=L(null);F(()=>{var g,R,W;if(!i)return;if(We.current!==pe){We.current=pe,ce.current=te;return}if(ce.current===te)return;let p=((R=JSON.parse((g=ce.current)!=null?g:"[]")[0])!=null?R:{}).org_id;if(ce.current=te,p===(M==null?void 0:M.org_id)&&A.current){k(!1),Je(1500),(W=h.current)==null||W.injectJavaScript(et(M!=null?M:{},Me));return}k(!1),ee(j=>j+1)},[te,i,pe]);let Et=Le(async p=>{var R,W,j,I,ye;let g=ze(p.nativeEvent.data);if(!g){if(d&&(l!=null&&l.onWebEvent))try{Promise.resolve(l.onWebEvent(p.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(g.method==="log"){let{level:y,text:P}=g;N(`web:${e}`,y!=null?y:"log",P!=null?P:"");return}if(g.method==="pong"){$.current||k(!0);return}if(g.method==="touchAtTop"){o.emit(!!g.at_top);return}if(g.method==="contextApplied"){$.current&&clearTimeout($.current),$.current=null,k(!0);return}if(g.method==="ready"){A.current=!0,k(!0);let y=(R=D.getState().instances[e])==null?void 0:R.context;y&&((W=h.current)==null||W.injectJavaScript(be(y)));return}try{let y=await it(g,{getHostData:()=>{var P,H;return(H=(P=D.getState().instances[e])==null?void 0:P.host_data)!=null?H:{}},getPermissions:()=>{var P,H;return d?(H=(P=x(d))==null?void 0:P.permissions)!=null?H:[]:[]},is_dark:r,close:oe,app_id:d!=null?d:"",instance_id:e,options:l});g.id&&((j=h.current)==null||j.injectJavaScript(Qe(g.id,y)))}catch(y){if(!g.id)return;let P=y==null?void 0:y.code,H=y instanceof _?y:new _(typeof P=="string"?P:"HOST_ERROR",String((I=y==null?void 0:y.message)!=null?I:y));(ye=h.current)==null||ye.injectJavaScript(Ye(g.id,H))}},[e,r,d,o,l]),Tt=Le(()=>{Z(!1),ee(p=>p+1),Be(p=>p+1)},[]);return ae($e,{style:[Fe.absoluteFill,a&&{backgroundColor:r?"#09090B":"#FFFFFF"},!n&&C.behind],pointerEvents:t?"auto":"none",children:[i?E(nn,{ref:h,source:{uri:i.entry_uri},originWhitelist:["*"],allowingReadAccessToURL:`file://${i.dir}`,allowFileAccess:!0,allowFileAccessFromFileURLs:!0,allowUniversalAccessFromFileURLs:!0,injectedJavaScriptBeforeContentLoaded:xt,onMessage:Et,bounces:!1,overScrollMode:"never",onLoadStart:p=>{N(`webview:${e}`,"load start",De(p.nativeEvent.url)),A.current=!1,k(!1)},onError:p=>{N(`webview:${e}`,"load error",De(p.nativeEvent.url),p.nativeEvent.description),Z(!0),k(!1)},onLoadEnd:p=>{let g=p.nativeEvent.url;N(`webview:${e}`,"load end",De(g)),d&&(f==null||f({app_id:d,instance_id:e,url:g})),Je(1500)},onContentProcessDidTerminate:()=>{A.current=!1,k(!1),ee(p=>p+1)},onRenderProcessGone:()=>(A.current=!1,k(!1),ee(p=>p+1),!0),style:C.webview},pe):null,m&&E(an,{visible:!i||!St,interactive:V,children:E(sn,{splash:c,app:m.app,is_dark:r,error:V,has_bundle:!!i,retry:Tt})})]})}),sn=Ne.memo(({splash:e,app:t,is_dark:n,error:r,has_bundle:s,retry:o})=>{let c=e,l=Ce(t.app_id),a=r?"error":!s&&(l==null?void 0:l.status)==="downloading"?"downloading":"loading";return E(c,{app:t,is_dark:n,status:a,progress:a==="downloading"?l==null?void 0:l.progress:void 0,retry:o})}),an=({visible:e,interactive:t,children:n})=>{let r=L(new Ie.Value(e?1:0)).current,[s,o]=Q(e);return F(()=>{if(e){o(!0),r.setValue(1);return}let c=Ie.timing(r,{toValue:0,duration:180,useNativeDriver:!0});return c.start(({finished:l})=>{l&&o(!1)}),()=>c.stop()},[e,r]),s?E(Ie.View,{style:[Fe.absoluteFill,{opacity:r}],pointerEvents:t?"auto":"none",children:n}):null},yt=({app:e,is_dark:t,status:n,progress:r,retry:s})=>{let o=t?"#FAFAFA":"#18181B";return ae($e,{style:[C.splash,{backgroundColor:t?"#09090B":"#FFFFFF"}],children:[E($e,{style:[C.splash_icon,{backgroundColor:t?"#18181B":"#F4F4F5"}],children:e.icon?E(en,{source:{uri:e.icon},style:C.splash_icon_image}):E(se,{style:C.splash_letter,children:(e.name||"?").slice(0,1).toUpperCase()})}),E(se,{style:[C.splash_name,{color:o}],children:e.name}),n==="error"?ae(Mt,{children:[E(se,{style:C.splash_hint,children:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c mini app"}),E(tn,{activeOpacity:.7,style:[C.retry_button,{backgroundColor:t?"#27272A":"#F4F4F5"}],onPress:s,children:E(se,{style:[C.retry_text,{color:o}],children:"Th\u1EED l\u1EA1i"})})]}):ae(Mt,{children:[E(Xt,{style:C.splash_spinner,color:t?"#A1A1AA":"#71717A"}),n==="downloading"&&ae(se,{style:C.splash_hint,children:["\u0110ang t\u1EA3i mini app",r?` ${Math.round(r*100)}%`:"\u2026"]})]})]})},wt=(e,t)=>{let n=L(t),r=L(!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.`))},pn=({container:e,splash:t=yt,is_dark:n=!1,bridge:r,close_on_back:s=!0,opaque_background:o=!0,onWebLoadEnd:c})=>{wt("container",e),wt("splash",t);let l=e,a=B(D,i=>i.active_key),f=L(a);a&&(f.current=a);let h=B(D,i=>Object.keys(i.instances).join("|")),A=B(D,i=>{var v;return i.active_key?(v=i.instances[i.active_key])==null?void 0:v.app.name:void 0}),m=we(()=>h?h.split("|"):[],[h]),[d,O]=Q({}),M=L(rn()).current;F(()=>{if(!a||!s)return;let i=Zt.addEventListener("hardwareBackPress",()=>(oe(),!0));return()=>i.remove()},[a,s]);let u=Le(()=>{let i=D.getState().active_key;i&&O(v=>({...v,[i]:(v[i]||0)+1}))},[]);return m.length?E(l,{visible:!!a,title:A!=null?A:"",is_dark:n,close:oe,reload:u,subscribeWebAtTop:M.subscribe,children:m.map(i=>E(on,{instance_key:i,is_active:a===i,is_front:(a!=null?a:f.current)===i,is_dark:n,reload_tick:d[i]||0,web_at_top:M,splash:t,bridge:r,opaque_background:o,onWebLoadEnd:c},i))}):null},C=Fe.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"}}),cn=Ne.memo(pn);export{yt as DefaultMiniAppSplash,_e as MINIAPP_PLATFORM_URL,cn as MiniAppHost,_ as MiniAppHostError,oe as closeMiniApp,Rt as configureMiniApp,Ct as createMmkvStorage,Pt as createRnfsFileSystem,ke as ensureMiniApp,x as getLocalMiniApp,mt as getMiniAppCatalogEntry,Kt as getMiniAppStatuses,Ut as onMiniAppEvent,Bt as openMiniApp,Yt as pauseMiniAppDownloads,Jt as preloadMiniApp,Gt as resumeMiniAppDownloads,$t as sendEventToWeb,Oe as syncMiniAppCatalog,ht as uninstallMiniApp,Ce as useMiniAppDownload,qt as useMiniAppDownloadsPaused};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retion-miniapp/react-native",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
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
  "keywords": [