yoyoawb
Version:
awb交互式应用框架
7 lines • 6.53 kB
JavaScript
/**
* 构建交互类
* v 1.0.97
* 作者:Yoyo,星辰
* 介绍:交互式App 依赖库
*/
const __mutual_cache=new Map();const __mutual_event=new Map();class Mutual{App;constructor(){this.#initAsyncJsPrompt();this.#appInit()}isJSON(str){try{JSON.parse(str);return true}catch(e){return false}}#appInit(){this.App=new Proxy({},{get:(target,key)=>new Proxy(target,{get:(target1,key1)=>(args,configJson)=>{args??={};configJson??={};configJson._time??=5000;configJson._time=Number(configJson._time);if(isNaN(Number(configJson._time)))configJson._time=5000;configJson._time=Math.abs(configJson._time);const ID=this.#generateUniqueID();const isSuccessful=this.#invoke(ID,key,key1,args,configJson);let isAppResult=this.isJSON(isSuccessful);let AppResultObj={};if(isAppResult){AppResultObj=JSON.parse(isSuccessful);if(AppResultObj.status){const binaryData=atob(String(AppResultObj.value));const utf8DecodedString=new TextDecoder('utf-8').decode(new Uint8Array([...binaryData].map(c=>c.charCodeAt(0))));AppResultObj.value=this.isJSON(utf8DecodedString)?JSON.parse(utf8DecodedString):utf8DecodedString}}if(typeof args?.success=='function'||typeof args?.fail=='function'||typeof args?.complete=='function'){const PrObj={};const resultObj=new Proxy(PrObj,{get:(t,k)=>{return(args)=>{window.Android?.asyncTaskPrompt(ID,k,JSON.stringify(args))}},set:(t,p,newValue,rec)=>{return t[p]=newValue}});if(!isSuccessful||!isAppResult){typeof args.fail=='function'&&args.fail({id:ID,message:'Interaction failure !'});typeof args.complete=='function'&&args.complete();return null}if(!AppResultObj.status){typeof args.fail=='function'&&args.fail({id:ID,message:AppResultObj.value??AppResultObj.message});typeof args.complete=='function'&&args.complete();return null}const cacheObj={base:{},result:PrObj,timeoutId:undefined};if(typeof args?.success=='function')cacheObj.base.success=args?.success;if(typeof args?.fail=='function')cacheObj.base.fail=args?.fail;if(typeof args?.complete=='function')cacheObj.base.complete=args?.complete;if(AppResultObj.exportType==1){typeof args.success=='function'&&args.success(AppResultObj.value);typeof args.complete=='function'&&args.complete();return null}if(configJson._time!==0){cacheObj.timeoutId=setTimeout(()=>{__mutual_cache.delete(ID);typeof args?.fail=='function'&&args?.fail({id:ID,message:'request timeout !'});typeof args?.complete=='function'&&args?.complete()},configJson._time)}__mutual_cache.set(ID,cacheObj);return resultObj}return new Promise((resolve,reject)=>{if(!isSuccessful||!isAppResult)return reject({id:ID,message:'Interaction failure !'});if(!AppResultObj.status)return reject({id:ID,message:AppResultObj.value??AppResultObj.message});if(AppResultObj.exportType==1){resolve(AppResultObj.value);return null}let timeoutId=undefined;if(configJson._time!==0){timeoutId=setTimeout(()=>{__mutual_cache.delete(ID);reject({id:ID,message:'request timeout !'})},configJson._time)}__mutual_cache.set(ID,[resolve,reject,timeoutId])})}})})}#invoke(ID,className,functionName,data,configJson){const isInvokeSucceed=window.Android?.asyncJavaPrompt(ID,JSON.stringify({...configJson,class:className,function:functionName}),JSON.stringify(data));return isInvokeSucceed}#initAsyncJsPrompt(){Object.defineProperty(window,'asyncJsPrompt',{value:(ID,data,plan)=>{ID??='';data??='';plan??=100;if(!__mutual_cache.has(ID))return false;const binaryData=atob(data);const utf8DecodedString=new TextDecoder('utf-8').decode(new Uint8Array([...binaryData].map(c=>c.charCodeAt(0))));try{const jsonData=JSON.parse(utf8DecodedString);const eventCallBack=__mutual_cache.get(ID);if(Array.isArray(eventCallBack)){if(plan>=100){if(jsonData.status){eventCallBack[0](jsonData.data)}else{eventCallBack[1](jsonData)}if(eventCallBack[2])clearTimeout(eventCallBack[2]);__mutual_cache.delete(ID)}}else{const{base,result,timeoutId}=eventCallBack;if(jsonData.event){const callbackFun=result[jsonData.event];typeof callbackFun=='function'&&callbackFun(jsonData.data)}if(plan>=100){if(jsonData.status){typeof base.success=='function'&&base.success(jsonData.data)}else{typeof base.fail=='function'&&base.fail(jsonData)}typeof base.complete=='function'&&base.complete();if(timeoutId)clearTimeout(timeoutId);__mutual_cache.delete(ID)}}}catch(e){console.error('应用调用数据格式错误:',e.message);return false}return true}})}#generateUniqueID(){const characters={str1:'abcdefghij',str2:'klmnopqrst',str3:'uvwxyztsrq',str4:'jihgfedcba',str5:'a1b2c3d4e5',str6:'f6g7h8i9j0',};let charactersStr='';const randtf=Math.floor(Math.random()*6)+1;charactersStr=characters[`str${randtf}`];let timestamp=new Date().getTime().toString();timestamp=timestamp.split('').reverse().join('');const snRand=Math.floor(Math.random()*9999)+1000;const snRand2=Math.floor(Math.random()*9999)+1000;timestamp+=snRand.toString().padStart(4,'0')+snRand2.toString().padStart(4,'0');let id='';for(let i=0;i<timestamp.length;i++){const digit=parseInt(timestamp[i],10);let character;if(digit%3===0){character=charactersStr[digit%10]}else if(digit%3===1){character=digit%10}else{character=charactersStr[digit%10].toUpperCase()}id+=character}return id}}class EventEmitter{constructor(){this.#initAsyncJsEventEmit()}#initAsyncJsEventEmit(){Object.defineProperty(window,'asyncJsEventEmit',{value:(eventName,data)=>{if(!__mutual_event.has(eventName))return false;const binaryData=atob(data);const utf8DecodedString=new TextDecoder('utf-8').decode(new Uint8Array([...binaryData].map(c=>c.charCodeAt(0))));try{const jsonData=JSON.parse(utf8DecodedString);for(const listener of __mutual_event.get(eventName)){listener.call(this,jsonData)}}catch(e){console.error('应用调用数据格式错误:',e.message);return false}return true}})}on(eventName,listener){if(!__mutual_event.has(eventName)){__mutual_event.set(eventName,new Set())}__mutual_event.get(eventName).add(listener)}once(eventName,listener){const wrapper=(...args)=>{listener.apply(this,args);this.off(eventName,wrapper)};this.on(eventName,wrapper)}off(eventName,listener){if(__mutual_event.has(eventName)){const listeners=__mutual_event.get(eventName);const matchingListeners=Array.from(listeners).filter(fn=>fn===listener);for(const matchingListener of matchingListeners){listeners.delete(matchingListener)}}}emit(eventName,...args){if(__mutual_event.has(eventName)){for(const listener of __mutual_event.get(eventName)){listener.apply(this,args)}}}}const mutualClass=new Mutual();const eventEmitterClass=new EventEmitter();export const app=mutualClass.App;export const eventEmitter=eventEmitterClass;