@jolibox/native-bridge 1.0.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/README.md ADDED
@@ -0,0 +1 @@
1
+ # Jolibox JSSDK Interface
@@ -0,0 +1,5 @@
1
+ import { On } from './js-bridge';
2
+ export declare const applyNative: jsb.service.ApplyNative, invokeNative: jsb.service.InvokeNative, onNative: jsb.service.OnNative, offNative: jsb.service.OnNative, subscribeHandler: import("./js-bridge").SubscribeHandler, publish: import("./js-bridge").Publish, subscribe: On, unsubscribe: import("./js-bridge").Off;
3
+ export declare const onNativeWithError: On;
4
+ export { RuntimeLoader } from './js-core';
5
+ export * from './types';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ var Ie=Object.defineProperty,Pe=Object.defineProperties;var Ce=Object.getOwnPropertyDescriptors;var M=Object.getOwnPropertySymbols;var te=Object.prototype.hasOwnProperty,ne=Object.prototype.propertyIsEnumerable;var re=(e,r,t)=>r in e?Ie(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,f=(e,r)=>{for(var t in r||(r={}))te.call(r,t)&&re(e,t,r[t]);if(M)for(var t of M(r))ne.call(r,t)&&re(e,t,r[t]);return e},ie=(e,r)=>Pe(e,Ce(r));var se=(e,r)=>{var t={};for(var i in e)te.call(e,i)&&r.indexOf(i)<0&&(t[i]=e[i]);if(e!=null&&M)for(var i of M(e))r.indexOf(i)<0&&ne.call(e,i)&&(t[i]=e[i]);return t};var R=(e,r,t)=>new Promise((i,n)=>{var s=u=>{try{o(t.next(u))}catch(c){n(c)}},a=u=>{try{o(t.throw(u))}catch(c){n(c)}},o=u=>u.done?i(u.value):Promise.resolve(u.value).then(s,a);o((t=t.apply(e,r)).next())});function De(e){return!!(e!=null&&e.__nativeBuffers__)}var Ue=e=>{let r=atob(e),t=r.length,i=new Uint8Array(t);for(let n=0;n<t;n++)i[n]=r.charCodeAt(n);return i.buffer};function x(e){if(typeof e=="string")try{e=JSON.parse(e)}catch(t){return{}}if(typeof e!="object"||e===null)return{};if(!De(e))return e;let r=e.__nativeBuffers__;if(delete e.__nativeBuffers__,r)for(let t=0;t<r.length;t++){let i=r[t];if(i){let n;i.value?n=i.value:i.base64&&(n=Ue(i.base64)),typeof n!="undefined"&&n instanceof ArrayBuffer&&(e[i.key]=n)}}return e}var Je=e=>{let r="",t=new Uint8Array(e),i=t.byteLength;for(let n=0;n<i;n++)r+=String.fromCharCode(t[n]);return btoa(r)};function oe(e={},r=!1){let t=e,i=[];for(let[n,s]of Object.entries(t))if(s!==void 0&&s instanceof ArrayBuffer&&s.byteLength!==void 0){let a=r?{value:s,key:n}:{base64:Je(s),key:n};i.push(a),delete t[n]}return i.length>0&&(t.__nativeBuffers__=i),t}var G=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertySymbols,Fe=Object.prototype.hasOwnProperty,Be=Object.prototype.propertyIsEnumerable,ce=(e,r,t)=>r in e?G(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,je=(e,r)=>{for(var t in r||(r={}))Fe.call(r,t)&&ce(e,t,r[t]);if(ae)for(var t of ae(r))Be.call(r,t)&&ce(e,t,r[t]);return e};var He=(e,r)=>{for(var t in r)G(e,t,{get:r[t],enumerable:!0})},le=(e,r,t,i)=>{for(var n=i>1?void 0:i?Le(r,t):r,s=e.length-1,a;s>=0;s--)(a=e[s])&&(n=(i?a(r,t,n):a(n))||n);return i&&n&&G(r,t,n),n},Ve=(e,r,t)=>new Promise((i,n)=>{var s=u=>{try{o(t.next(u))}catch(c){n(c)}},a=u=>{try{o(t.throw(u))}catch(c){n(c)}},o=u=>u.done?i(u.value):Promise.resolve(u.value).then(s,a);o((t=t.apply(e,r)).next())});if(typeof window!="undefined"&&!window.AbortController){let e=function(){this.signal=new r};e.prototype.abort=function(){this.signal._aborted=!0,typeof this.signal.onabort=="function"&&this.signal.onabort(new Event("abort"));let t=new Event("abort");this.signal.dispatchEvent(t)};let r=function(){this._aborted=!1,this.aborted=!1,this.onabort=null,this._eventListeners={}};Object.defineProperty(r.prototype,"aborted",{get:function(){return this._aborted}}),r.prototype.addEventListener=function(t,i){this._eventListeners[t]||(this._eventListeners[t]=[]),this._eventListeners[t].push(i)},r.prototype.removeEventListener=function(t,i){if(!this._eventListeners[t])return;let n=this._eventListeners[t].indexOf(i);n!==-1&&this._eventListeners[t].splice(n,1)},r.prototype.dispatchEvent=function(t){if(this._eventListeners[t.type])for(let i of this._eventListeners[t.type])i.call(this,t)},window.AbortController=e,window.AbortSignal=r}function Ke(e){return new Promise(r=>{setTimeout(()=>{r()},e)})}var de=class{constructor(){this.state="pending",this.promise=new Promise((e,r)=>{this.resolve=t=>{this.state==="pending"&&(this.state="fulfilled",e(t))},this.reject=t=>{this.state==="pending"&&(this.state="rejected",r(t))}})}};function z(e){return typeof e=="string"}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!(e instanceof RegExp)&&!(e instanceof Date)}function $e(e){return typeof e=="undefined"}function Ge(e){return $e(e)||e===null}function me(e){return typeof e=="function"}function ge(e){return y(e)&&me(e.then)}function fe(e){let r=e,t=null,i=function(...n){return t||(t=new r(...n)),t};return i.prototype=r.prototype,i}var ze=(e=>(e[e.DEVELOPER_FILE_NOT_FOUND=0]="DEVELOPER_FILE_NOT_FOUND",e[e.INTERNAL_IOS_CAN_NOT_FOUND_PKG=1]="INTERNAL_IOS_CAN_NOT_FOUND_PKG",e[e.USER_IOS_LOAD_TIMEOUT=2]="USER_IOS_LOAD_TIMEOUT",e[e.INTERNAL_IOS_PKG_LOAD_ERROR=3]="INTERNAL_IOS_PKG_LOAD_ERROR",e[e.INTERNAL_IOS_PKG_PARSE_FAIL=4]="INTERNAL_IOS_PKG_PARSE_FAIL",e[e.USER_IOS_GET_EMPTY_DATA=5]="USER_IOS_GET_EMPTY_DATA",e[e.USER_ANDROID_GET_PKG_FAIL=6]="USER_ANDROID_GET_PKG_FAIL",e[e.DEVELOPER_ANDROID_PACKAGE_FILE_UNEXPECTED_REQUIRE=7]="DEVELOPER_ANDROID_PACKAGE_FILE_UNEXPECTED_REQUIRE",e))(ze||{}),We=class extends Error{constructor(e){if(typeof e=="string"){super(e),this.priority="P1";return}super(e.message),this.priority="P1",this.stack=e.stack,this.raw=e}},P=class extends We{constructor(){super(...arguments),this.kind="INTERNAL_ERROR"}};var pe=class extends P{constructor(){super(...arguments),this.name="INTERNAL_INVOKE_NATIVE_ERROR"}},he=class extends P{constructor(e,r,t,i){super(e),this.errNo=r,this.name="INTERNAL_APPLY_NATIVE_ERROR",this.errorType=t,this.errorCode=i}};var ve=class extends P{constructor(){super(...arguments),this.name="INTERNAL_JSCORE_ERROR",this.priority="P0"}};var C=class extends P{constructor(){super(...arguments),this.name="INTERNAL_METRIC_REPORT_ERROR"}};function k(e){return(...r)=>{var t,i;((i=(t=globalThis.VConsole)==null?void 0:t[e])!=null?i:globalThis.console[e])(...r)}}var D={log:k("log"),warn:k("warn"),info:k("info"),error:k("error"),debug:k("debug")};Object.assign(globalThis,{logger:D});var Qe=Symbol.for("Jolibox.canIUseMap"),Xe={};globalThis[Qe]=Xe;var qe=(e=>(e[e.System=1e3]="System",e[e.ErrorTrace=1001]="ErrorTrace",e[e.UserDefined=1002]="UserDefined",e))(qe||{}),Ye=(e=>(e.MiniGame="mini-game",e.MiniDrama="mini-drama",e.App="app",e.WebSDK="web-sdk",e.AppSDK="app-sdk",e))(Ye||{}),Ze=(e=>(e[e.App=0]="App",e[e.H5=1]="H5",e[e.Weapp=2]="Weapp",e[e.Alipay=3]="Alipay",e[e.Gcash=4]="Gcash",e[e.Dana=5]="Dana",e[e.Umma=6]="Umma",e[e.WebSDK=1e3]="WebSDK",e[e.AppSDK=1001]="AppSDK",e[e.Other=9999]="Other",e))(Ze||{});var pr={isiOS:navigator.userAgent.includes("iPhone")||navigator.userAgent.includes("iPod")||navigator.userAgent.includes("iPad")||navigator.userAgent.includes("iPhone OS"),iosVersion:()=>{let e=navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);return[parseInt(e[1],10),parseInt(e[2],10),parseInt(e[3]||"0",10)]},isAndroid:navigator.userAgent.includes("Android"),isMac:navigator.userAgent.includes("Mac"),isFacebook:navigator.userAgent.includes("FB_IAB"),isPC:!navigator.userAgent.includes("iPhone")&&!navigator.userAgent.includes("Android")};var H=class V{constructor(r){this.element=r,this.next=V.Undefined,this.prev=V.Undefined}};H.Undefined=new H(void 0);var d=H,er=class{constructor(){this._first=d.Undefined,this._last=d.Undefined,this._size=0}get size(){return this._size}isEmpty(){return this._first===d.Undefined}clear(){let e=this._first;for(;e!==d.Undefined;){let r=e.next;e.prev=d.Undefined,e.next=d.Undefined,e=r}this._first=d.Undefined,this._last=d.Undefined,this._size=0}unshift(e){return this._insert(e,!1)}push(e){return this._insert(e,!0)}_insert(e,r){let t=new d(e);if(this._first===d.Undefined)this._first=t,this._last=t;else if(r){let n=this._last;this._last=t,t.prev=n,n.next=t}else{let n=this._first;this._first=t,t.next=n,n.prev=t}this._size+=1;let i=!1;return()=>{i||(i=!0,this._remove(t))}}shift(){if(this._first!==d.Undefined){let e=this._first.element;return this._remove(this._first),e}}pop(){if(this._last!==d.Undefined){let e=this._last.element;return this._remove(this._last),e}}_remove(e){if(e.prev!==d.Undefined&&e.next!==d.Undefined){let r=e.prev;r.next=e.next,e.next.prev=r}else e.prev===d.Undefined&&e.next===d.Undefined?(this._first=d.Undefined,this._last=d.Undefined):e.next===d.Undefined?(this._last=this._last.prev,this._last.next=d.Undefined):e.prev===d.Undefined&&(this._first=this._first.next,this._first.prev=d.Undefined);this._size-=1}*[Symbol.iterator](){let e=this._first;for(;e!==d.Undefined;)yield e.element,e=e.next}},rr=0,I=class{constructor(e){this.value=e,this.id=rr++}},T=class{constructor(e){this.options=e,this._size=0}dispose(e){var r,t;this._disposed||(this._disposed=!0,this._listeners&&(e?(this._listeners instanceof I&&(this._listeners=[this._listeners]),this._listeners=this._listeners.filter(i=>(i==null?void 0:i.value)===e)):(this._listeners=void 0,this._size=0)),(t=(r=this.options)==null?void 0:r.onDidRemoveLastListener)==null||t.call(r))}get event(){var e;return(e=this._event)!=null||(this._event=(r,t)=>{var i,n,s,a,o,u;if(this._disposed)return()=>{console.info("[Jolibox SDK] Emitter is _disposed")};t&&(r=r.bind(t));let c=new I(r);this._listeners?this._listeners instanceof I?this._listeners=[this._listeners,c]:this._listeners.push(c):((n=(i=this.options)==null?void 0:i.onWillAddFirstListener)==null||n.call(i,this),this._listeners=c,(a=(s=this.options)==null?void 0:s.onDidFirstListener)==null||a.call(s,this)),(u=(o=this.options)==null?void 0:o.onDidAddListener)==null||u.call(o,this),this._size++}),this._event}_deliver(e,r){var t;if(!e)return;let i=((t=this.options)==null?void 0:t.onListenerError)||Error.constructor;if(!i){e.value(r);return}try{e.value(r)}catch(n){i(n)}}fire(e){this._listeners&&(this._listeners instanceof I?this._deliver(this._listeners,e):this._listeners.forEach(r=>this._deliver(r,e)))}hasListeners(){return this._size>0}},U=class{constructor(){this.listeners=new Map,this.listerHandlerMap=new WeakMap,this.cachedEventQueue=new Map}on(e,r){var t;let i=(t=this.listeners.get(e))!=null?t:new T,n=a=>r(...a.args);this.listerHandlerMap.set(r,n),i.event(n),this.listeners.set(e,i);let s=this.cachedEventQueue.get(e);if(s)for(;s.size>0;)i.fire(je({event:e},s.shift()))}off(e,r){let t=this.listeners.get(e);if(t){let i=this.listerHandlerMap.get(r);t.dispose(i)}}emit(e,...r){let t=this.listeners.get(e);if(t)t.fire({event:e,args:r});else{let i=this.cachedEventQueue.get(e);i||(i=new er,this.cachedEventQueue.set(e,i)),i.push({args:r})}}},K={};He(K,{None:()=>tr,filter:()=>ir,once:()=>be,toPromise:()=>nr});var tr=()=>{console.log("[Jolibox SDK] None Event")};function nr(e){return new Promise(r=>be(e)(r))}function be(e){return(r,t=null)=>{let i=!1;return e(n=>{if(!i)return i=!0,r.call(t,n)},null)}}function ir(e,r){return(t=>{let i,n={onWillAddFirstListener(){i=t(s.fire,s)}},s=new T(n);return s.event})((t,i=null)=>e(n=>r(n)&&t.call(i,n),null))}var j=Symbol.for("Jolibox.hostEmitter"),sr=()=>{let e=new U;return globalThis[j]||(globalThis[j]={on:e.on.bind(e),off:e.off.bind(e),emit:e.emit.bind(e)}),globalThis[j]},hr=sr();function or(e,r){let t=Math.min(e.length,r.length);for(let i=0;i<t;i++)ar(e[i],r[i])}function ar(e,r){if(z(r)){if(typeof e!==r)throw new Error(`argument does not match constraint: typeof ${r}`)}else if(me(r)){try{if(e instanceof r)return}catch(t){}if(!Ge(e)&&e.constructor===r||r.length===1&&r.call(void 0,e)===!0)return;throw new Error("[Jolibox SDK]argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true")}}var $=class{constructor(){this._commands=new Map,this._onDidRegisterCommand=new T,this.onDidRegisterCommand=this._onDidRegisterCommand.event,console.log("[Jolibox SDK] command registry")}registerCommand(e){if(!e)throw new Error("invalid command");if(e.metadata&&Array.isArray(e.metadata.args)){let t=[];for(let n of e.metadata.args)t.push(n.constraint);let i=e.handler;e.handler=function(...n){return or(n,t),i(...n)}}let{id:r}=e;this._commands.get(r)&&console.info(`[Jolibox SDK] duplicated command is registered ${r}`),this._commands.set(r,e),this._onDidRegisterCommand.fire(r)}getCommand(e){return this._commands.get(e)}getCommands(){let e=new Map;for(let r of this._commands.keys()){let t=this.getCommand(r);t&&e.set(r,t)}return e}};$=le([fe],$);var ue=class{constructor(){this._onWillExecuteCommand=new T,this.onWillExecuteCommand=this._onWillExecuteCommand.event,this._onDidExecuteCommand=new T,this.onDidExecuteCommand=this._onDidExecuteCommand.event,this.registry=new $,this._starActivation=null}_activateStar(){return this._starActivation||(this._starActivation=Ke(3e4)),this._starActivation}executeCommand(e,...r){return Ve(this,null,function*(){return this.registry.getCommand(e)?this._tryExecuteCommand(e,r):(yield Promise.all([Promise.race([this._activateStar(),K.toPromise(K.filter(this.registry.onDidRegisterCommand,t=>t===e))])]),this._tryExecuteCommand(e,r))})}executeCommandThowErr(e,...r){if(!this.registry.getCommand(e))throw new Error(`command '${e}' not found`);let t=this.registry.getCommand(e);this._onWillExecuteCommand.fire({commandId:e,args:r});let i=this.invokeFunction(t.handler,...r);return this._onDidExecuteCommand.fire({commandId:e,args:r}),i}_tryExecuteCommand(e,r){let t=this.registry.getCommand(e);if(!t)return Promise.reject(new Error(`command '${e}' not found`));try{this._onWillExecuteCommand.fire({commandId:e,args:r});let i=this.invokeFunction(t.handler,...r);return this._onDidExecuteCommand.fire({commandId:e,args:r}),Promise.resolve(i)}catch(i){return Promise.reject(i)}}invokeFunction(e,...r){let t=!1;try{return e(...r)}finally{t=!0}}};ue=le([fe],ue);var vr=Symbol.for("Jolibox.commands");function O(e,r){return`[${e}]:${r}`}var _="custom_event_";var ye=[],_e=[],Ee=["env","createRequestTask","login"],J="__batch_event__";var cr=e=>e==="pv"?e:"default",E=class{constructor(r){this.interval=30;this.lastReportTime=0;this.cache={};let{reporter:t,interval:i=30,eventName:n,tagNameOrder:s,metricName:a,type:o}=r;this.reporter=t,this.interval=i,this.eventName=n,this.tagNameOrder=s,this.metricName=a,this.type=cr(o)}report(r){this.type==="pv"?this.addPVPoint(r):this.addPoint(r),this.tryReport(!1)}flush(){this.tryReport(!0)}tryReport(r){if(Object.keys(this.cache).length){if(r){this.reporter(this.processPoints(this.cache)),this.clearPoints();return}this.lastReportTime=this.lastReportTime||Date.now(),Date.now()-this.lastReportTime>=this.interval*1e3&&(this.reporter(this.processPoints(this.cache)),this.clearPoints(),this.lastReportTime=Date.now())}}addPoint(r){let t=(i,n,s,a)=>{let o=n.shift();if(o){let u=a[o];i[u]||(i[u]={}),t(i[u],n,s,a)}else i[s]||(i[s]=[]),i[s].push(a[s])};t(this.cache,[...this.tagNameOrder],this.metricName,r)}addPVPoint(r){let t=(n,s,a,o)=>{let u=s.shift();if(!u&&y(o))throw new C(`report value failed to match tagNameOrder, ${JSON.stringify(i)}`);if(u){let c=[];if(y(o))c.push(...Object.keys(o));else if(z(o)){if(s.length>0)throw new C(`report value failed to match tagNameOrder, ${JSON.stringify(i)}`);c.push(o)}else throw new C(`expected metric value to be a string, but got a(n) ${typeof o}, ${JSON.stringify(i)}`);c.forEach(l=>{n[l]||(n[l]={});let m=y(o)?o[l]:o;t(n[l],[...s],a,m)})}else n[a]?n[a]++:n[a]=1},i={point:r,metricName:this.metricName,tagNameOrder:this.tagNameOrder};t(this.cache,[...this.tagNameOrder],this.metricName,r)}processPoints(r){return{eventName:this.eventName,tagNameOrder:this.tagNameOrder,metricName:this.metricName,metricAggregateType:this.type==="pv"?"itoa":"arr",data:r}}clearPoints(){this.cache={}}},Ne=!1,W,Q,X;function Se(e,r){Ne||(W=new E({eventName:"jolibox_invoke",tagNameOrder:["status","method","errNo","errMsg","isForeground"],metricName:"duration",reporter(n){e.invoke("track",JSON.stringify({event:"reportMetrics",data:n}),-1)}}),Q=new E({eventName:"jolibox_invoke_js2native",tagNameOrder:["status","method","isForeground"],metricName:"duration",reporter(n){e.invoke("track",JSON.stringify({event:"reportMetrics",data:n}),-1)}}),X=new E({eventName:"jolibox_invoke_native2js",tagNameOrder:["status","method","isForeground"],metricName:"duration",reporter(n){e.invoke("track",JSON.stringify({event:"reportMetrics",data:n}),-1)}}),r("onJoliboxEnterBackground",()=>{W.flush(),Q.flush(),X.flush()}),Ne=!0);function t(n){var N,S;let{method:s,args:a,startTime:o,isForeground:u,errMsg:c=`${s}:fail no errMsg`,errNo:l=0,__timing:m={receiveJSInvoke:0,invokeCallback:0}}=n,{receiveJSInvoke:p,invokeCallback:v}=m,A=(S=(N=c.match(/\S:(\S+)\s?/))==null?void 0:N[1])!=null?S:"fail";W.report({status:A,method:i(s,a),errNo:`${l}`,errMsg:c,isForeground:u,duration:Date.now()-o}),o&&p&&v&&(Q.report({status:A,method:s,isForeground:u,duration:Number((p-o).toFixed(3))}),X.report({status:A,method:s,isForeground:u,duration:Number((Date.now()-v).toFixed(3))}))}function i(n,s){return(n==="callHostMethod"||n==="callHostMethodSync")&&s!=null&&s.method?`${n}-${s.method}`:n}return t}var q=[],ur=!1;function xe(e,r){let t=0,i=!0,n=new Map,s=Se(e,r);r("onJoliboxEnterBackground",()=>{i=!1}),r("onJoliboxEnterForeground",()=>{i=!0,q.forEach(p=>R(this,[p],function*({method:c,args:l,resolve:m}){let v=yield o(c,l);m(v)})),q.length=0});let a=(c,l)=>{let m=n.get(Number(c));if(!m)return;let p=x(l);m(p),n.delete(Number(c))},o=(c,l)=>{var Z,ee;let m=Date.now(),p=`${i}`;t+=1;let v=new de;if(n.set(t,v.resolve),!i&&_e.includes(c))return new Promise(h=>{q.push({method:c,args:l,resolve:h})});let N=ie(f({},{method:c,startTime:m,args:l,isForeground:p}),{invokeType:"js-bridge"}),S=!ur&&ye.includes(c),F=oe(l,S),B=S?F:JSON.stringify(F),g;if(c.endsWith("Sync")||Ee.includes(c)?g=(Z=e.call)==null?void 0:Z.call(e,c,F,t):typeof B=="string"?g=e.invoke(c,B,t):g=(ee=e.call)==null?void 0:ee.call(e,c,B,t),g){try{typeof g=="string"&&(g=JSON.parse(g)),g=x(g)}catch(h){D.error(h)}return n.delete(t),g.errorCode&&(g.errorCode=O(c,g.errorCode)),s(f(f({},N),g)),g}return c.endsWith("Sync")&&n.delete(t),v.promise.then(h=>(h.errorCode&&(h.errorCode=O(c,h.errorCode)),s(f(f({},N),h)),h))};return{invokeNative:o,applyNative:(c,l)=>{let m=o(c,l);return ge(m)?m.then(p=>Re(c,p)):Re(c,m)},invokeHandler:a}}function Re(e,r){if(!y(r)){D.warn(`[Jolibox SDK]${e} no response value`);return}let o=r,{errMsg:t,errNo:i,errorType:n,errorCode:s}=o,a=se(o,["errMsg","errNo","errorType","errorCode"]);if(t&&t!==`${e}:ok`)throw new he(t,i,n,s);return a}function ke(e){let r=new U,t=new U,i=new E({eventName:"jolibox_publish",tagNameOrder:["type","event"],metricName:"duration",reporter(n){e.invoke("track",JSON.stringify({event:"reportMetrics",data:n}),-1)}});return r.on("onJoliboxEnterBackground",()=>{i.flush()}),{onNative:r.on.bind(r),offNative:r.off.bind(r),subscribe:t.on.bind(t),unsubscribe:t.off.bind(t),subscribeHandler(n,s,a){let o=x(s),u;if(o.__extra){u=o.params;let{type:c,startTime:l}=o.__extra;i.report({type:c,event:n,duration:Date.now()-l})}else u=o;if(n===J){u.forEach(l=>{let[m,p]=l;try{t.emit(m.slice(_.length),p,a)}catch(v){}});return}if(n.startsWith(_)){t.emit(n.slice(_.length),u,a);return}r.emit(n,u,a)}}}function Te(e){let r=new Map,t;return(n,s,a,o)=>{if(o){let c=a?[a]:"*";e.publish(`${_}${n}`,s,c);return}t||(t=Promise.resolve().then(()=>{r.forEach((c,l)=>{try{let m=l?[l]:"*";e.publish(J,c,m)}catch(m){}}),t=void 0,r.clear()}));let u=r.get(a);u||(u=[],r.set(a,u)),u.push([`${_}${n}`,s])}}function Y(e){let{subscribeHandler:r,onNative:t,offNative:i,subscribe:n,unsubscribe:s}=ke(e),{invokeNative:a,invokeHandler:o,applyNative:u}=xe(e,t),c=Te(e);return{invokeHandler:o,subscribeHandler:r,applyNative:u,invokeNative:a,onNative:t,offNative:i,publish:c,subscribe:n,unsubscribe:s}}function L(e,r){return{params:e,__extra:{startTime:Date.now(),type:r}}}var w,b={trigger(){},exit(){return Promise.resolve(!1)},onReady(e){b.trigger=e},onDoExit(e){b.exit=e}},Oe=e=>{let r=window.prompt("invoke",JSON.stringify({event:"envSync",paramsString:JSON.stringify({})}));if(!r)e.onError(new pe("native env failed"));else{let{data:t}=JSON.parse(r);return t!=null?t:void 0}};if(window.webkit){let e=window.webkit.messageHandlers,r=(n="")=>{b.trigger(),e.onDocumentReady.postMessage({path:n})},t=n=>R(void 0,null,function*(){let s=yield b.exit();e.doExit.postMessage({uuid:n,shouldInterrupt:s})});w={onDocumentReady:r,doExit:t,invoke(n,s,a){e.invoke.postMessage({event:n,paramsString:s,callbackId:a})},publish(n,s,a){let o=L(s,"joliboxJSCore");window.prompt("publish",JSON.stringify({event:n,paramsString:JSON.stringify(o),webviewIds:a}))},call(n,s,a){let o=window.prompt("invoke",JSON.stringify({event:n,paramsString:JSON.stringify(s),callbackId:a}));if(o)return JSON.parse(o)}};let i={onDocumentReady:r,env:Oe,doExit:t};globalThis.joliboxJSCore=f({},i)}if(window.JoliAndroidSDKBridge){let e=window.JoliAndroidSDKBridge,r=(n="")=>{b.trigger(),e.onDocumentReady(JSON.stringify({path:n}))},t=n=>R(void 0,null,function*(){let s=yield b.exit();e.doExit(JSON.stringify({uuid:n,shouldInterrupt:s}))});w={onDocumentReady:r,invoke(n,s,a){e.invoke(JSON.stringify({event:n,paramsString:s,callbackId:a}))},doExit:t,publish(n,s,a){let o=L(s,"joliboxJSCore");e.publish({event:n,paramsString:JSON.stringify(o),webviewIds:a})},call(n,s,a){let o=window.prompt("invoke",JSON.stringify({event:n,paramsString:JSON.stringify(s),callbackId:a}));if(o)return JSON.parse(o)}};let i={onDocumentReady:r,env:Oe,doExit:t};globalThis.joliboxJSCore=f({},i)}var Ae=w;if(!Ae)throw new ve("No joliboxJScore is found, native bridge not found.");var lr=f({},Ae),Me=Y(lr),{invokeHandler:we}=Me,{applyNative:Et,invokeNative:Nt,onNative:dr,offNative:St,subscribeHandler:mr,publish:Rt,subscribe:xt,unsubscribe:kt}=Me,Tt=(e,r)=>{dr(e,(...t)=>{var i;(i=t[0])!=null&&i.errorCode&&(t[0].errorCode=O(e,t[0].errorCode)),r(...t)})};globalThis.joliboxJSBridge={callHandler:we,invokeHandler:we,subscribeHandler:mr};export{b as RuntimeLoader,Et as applyNative,Nt as invokeNative,St as offNative,dr as onNative,Tt as onNativeWithError,Rt as publish,xt as subscribe,mr as subscribeHandler,kt as unsubscribe};
@@ -0,0 +1,6 @@
1
+ export declare const CUSTOM_EVENT_PREFIX = "custom_event_";
2
+ export declare const HOST_EVENT_PREFIX = "host_event_";
3
+ export declare const BUFFER_METHODS: string[];
4
+ export declare const BACKGROUND_FORBIDDEN_METHODS: string[];
5
+ export declare const SYNC_METHODS: string[];
6
+ export declare const BATCH_EVENT = "__batch_event__";
@@ -0,0 +1,2 @@
1
+ export { createBridge } from './js-bridge';
2
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ import { InvokeHandler, On } from './types';
2
+ interface Invokes {
3
+ /** 暴露给宿主, 触发调用的方法 */
4
+ invokeHandler: InvokeHandler;
5
+ /** 基础库内部, 调用宿主的方法, 返回 native 返回对象 */
6
+ invokeNative: (method: string, args?: Record<string, unknown>, webviewId?: number) => any;
7
+ /** 基础库内部, 调用宿主的方法, 会根据 errMsg throwError */
8
+ applyNative: (method: string, args?: Record<string, unknown>, webviewId?: number) => any;
9
+ }
10
+ export declare function createInvoke(jsCore: jsb.JSCore, onNative: On): Invokes;
11
+ export declare function ifThrowError(method: string, res: {
12
+ errMsg?: string;
13
+ errNo?: number;
14
+ errorType?: string;
15
+ errorCode?: number;
16
+ }): {} | undefined;
17
+ export declare class ApplyNativeError extends Error {
18
+ readonly errNo?: number | undefined;
19
+ constructor(message: string, errNo?: number | undefined);
20
+ }
21
+ export {};
@@ -0,0 +1,6 @@
1
+ import { JSBridge } from './types';
2
+ /**
3
+ * build js-bridge
4
+ * @param jsCore jsCore function inject by native
5
+ */
6
+ export declare function createBridge(jsCore: jsb.JSCore): JSBridge;
@@ -0,0 +1 @@
1
+ export declare function createPublish(jsCore: jsb.JSCore): (event: string, data: Record<string, unknown>, webviewId?: number, force?: boolean) => void;
@@ -0,0 +1,63 @@
1
+ import { On } from './types';
2
+ type MetricReporter = (points: unknown) => unknown;
3
+ interface MetricCache {
4
+ [props: string]: MetricCache | (number | string)[];
5
+ }
6
+ interface PVMetricCache {
7
+ [props: string]: PVMetricCache | number;
8
+ }
9
+ type MetricCacheType = MetricCache | PVMetricCache;
10
+ type MetricType = 'pv' | 'default';
11
+ type Prettier<T> = T extends Record<string, unknown> ? {
12
+ [K in keyof T]: T[K];
13
+ } : T;
14
+ type MetricPoint<Tag extends string, Name extends string> = Prettier<{
15
+ [k in Tag]: string;
16
+ } & {
17
+ [K in Name]: number | string;
18
+ }>;
19
+ interface PVPoint {
20
+ [props: string]: string | JSON;
21
+ }
22
+ interface MetricConfig<Tag extends string, Name extends string, Type extends string> {
23
+ reporter: MetricReporter;
24
+ interval?: number;
25
+ eventName: string;
26
+ tagNameOrder: Tag[];
27
+ metricName: Name;
28
+ type?: Type;
29
+ }
30
+ export declare class MetricsMonitor<Tag extends string, Name extends string, Type extends string> {
31
+ reporter: MetricReporter;
32
+ interval: number;
33
+ lastReportTime: number;
34
+ cache: MetricCacheType;
35
+ eventName: string;
36
+ tagNameOrder: Tag[];
37
+ metricName: Name;
38
+ type: MetricType;
39
+ constructor(config: MetricConfig<Tag, Name, Type>);
40
+ report(point: Type extends 'pv' ? PVPoint : MetricPoint<Tag, Name>): void;
41
+ flush(): void;
42
+ private tryReport;
43
+ private addPoint;
44
+ private addPVPoint;
45
+ private processPoints;
46
+ private clearPoints;
47
+ }
48
+ interface InvokeMetrics {
49
+ errMsg: string;
50
+ errNo?: number;
51
+ __timing?: {
52
+ receiveJSInvoke: number;
53
+ invokeCallback: number;
54
+ };
55
+ method: string;
56
+ startTime: number;
57
+ args?: Record<string, unknown>;
58
+ isForeground: string;
59
+ [prop: string]: unknown;
60
+ }
61
+ export type reportInvokeFn = (invokeMetrics: InvokeMetrics) => void;
62
+ export declare function createReportInvokeMetrics(jsCore: jsb.JSCore, onNative: On): reportInvokeFn;
63
+ export {};
@@ -0,0 +1,10 @@
1
+ import { Off, On } from './types';
2
+ import { AnyFunction } from '@jolibox/types';
3
+ export interface Subscribes {
4
+ onNative: On;
5
+ offNative: Off;
6
+ subscribeHandler: AnyFunction;
7
+ subscribe: On;
8
+ unsubscribe: Off;
9
+ }
10
+ export declare function createSubscribe(jsCore: jsb.JSCore): Subscribes;
@@ -0,0 +1,18 @@
1
+ export type Listener = (...args: any[]) => any;
2
+ export type On = <T extends string>(event: T, handler: Listener) => void;
3
+ export type Off = <T extends string>(event: T, handler: Listener) => void;
4
+ export type InvokeHandler = (callbackId: string | number, data: string | Record<string, unknown>) => void;
5
+ export type Publish = (event: string, data: Record<string, unknown>, webviewId?: number, force?: boolean) => void;
6
+ export type SubscribeHandler = (event: string, data: string | Record<string, unknown>, webviewId?: number) => void;
7
+ export type AnyFunction = (...args: any[]) => any;
8
+ export interface JSBridge {
9
+ invokeHandler: InvokeHandler;
10
+ subscribeHandler: SubscribeHandler;
11
+ invokeNative: jsb.service.InvokeNative;
12
+ applyNative: jsb.service.ApplyNative;
13
+ onNative: jsb.service.OnNative;
14
+ offNative: jsb.service.OffNative;
15
+ publish: Publish;
16
+ subscribe: On;
17
+ unsubscribe: Off;
18
+ }
@@ -0,0 +1,17 @@
1
+ export interface DataObj {
2
+ params?: Record<string, unknown>;
3
+ errorCode?: number;
4
+ __extra?: {
5
+ startTime: number;
6
+ type: string;
7
+ };
8
+ __nativeBuffers__?: NativeBufferElement[] | undefined;
9
+ }
10
+ interface NativeBufferElement {
11
+ key: string;
12
+ value?: ArrayBuffer;
13
+ base64?: string;
14
+ }
15
+ export declare function unpack(data: unknown): DataObj;
16
+ export declare function pack(_data?: {}, useArrayBuffer?: boolean): Record<string, unknown>;
17
+ export {};
@@ -0,0 +1,2 @@
1
+ export { joliboxJSCore, RuntimeLoader } from './jolibox-js-core';
2
+ export { normalizeParams } from './utils';
@@ -0,0 +1,50 @@
1
+ export declare let joliboxJSCore: jsb.JSCore | undefined;
2
+ declare global {
3
+ interface Window {
4
+ JoliAndroidSDKBridge?: {
5
+ invoke: (invokeString: string) => void;
6
+ onDocumentReady: (paramsstr: string) => void;
7
+ doExit: (uuidString: string) => void;
8
+ publish: (params: {
9
+ event: string;
10
+ webviewIds: number[] | '*';
11
+ paramsString: string;
12
+ }) => void;
13
+ };
14
+ webkit?: {
15
+ messageHandlers: {
16
+ invoke: {
17
+ postMessage: (params: {
18
+ event: string;
19
+ callbackId: number;
20
+ paramsString: string;
21
+ }) => void;
22
+ };
23
+ publish: {
24
+ postMessage: (params: {
25
+ event: string;
26
+ webviewIds: number[] | '*';
27
+ paramsString: string;
28
+ }) => void;
29
+ };
30
+ onDocumentReady: {
31
+ postMessage: (params: {
32
+ path: string;
33
+ }) => void;
34
+ };
35
+ doExit: {
36
+ postMessage: (params: {
37
+ uuid: string;
38
+ shouldInterrupt: boolean;
39
+ }) => void;
40
+ };
41
+ };
42
+ };
43
+ }
44
+ }
45
+ export declare const RuntimeLoader: {
46
+ trigger(): void;
47
+ exit(): Promise<boolean>;
48
+ onReady(fn: () => void): void;
49
+ onDoExit(fn: () => Promise<boolean>): void;
50
+ };
@@ -0,0 +1,7 @@
1
+ export declare function normalizeParams(params: Record<string, unknown>, type: string): {
2
+ params: Record<string, unknown>;
3
+ __extra: {
4
+ startTime: number;
5
+ type: string;
6
+ };
7
+ };
@@ -0,0 +1,27 @@
1
+ export declare global {
2
+ namespace jsb {
3
+ interface JSCore {
4
+ invoke: (method: string, params: string, callbackId: number) => string | Record<string, unknown> | void;
5
+
6
+ // publish: (event: string, data: Record<string, unknown>, webviewIds: number[]) => void;
7
+
8
+ // 安卓 Webview 没有call
9
+ call?: (
10
+ method: string,
11
+ params: Record<string, unknown>,
12
+ callbackId: number
13
+ ) => string | Record<string, unknown> | void;
14
+
15
+ onDocumentReady: (path: string) => void;
16
+ doExit: (uuid: string) => void;
17
+ bind?: (id: number, handler: (...args: unknown[]) => unknown) => void;
18
+ publish: (event: string, data: unknown, webviewIds: number[] | '*') => void;
19
+ }
20
+
21
+ type ApplyNativeReturn<T> = T extends Promise<infer U>
22
+ ? Promise<Omit<U, 'errMsg' | 'errNo'>>
23
+ : Omit<T, 'errMsg' | 'errNo'>;
24
+ }
25
+ }
26
+
27
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './native-method.d';
2
+ export * from './global.d';
3
+ export * from './native-method-map.d';
@@ -0,0 +1,329 @@
1
+ import { Env, ISystemInfo } from '@jolibox/types';
2
+
3
+ declare global {
4
+ namespace jsb.service {
5
+ type NativeTaskPointEvent =
6
+ | 'OpenGame'
7
+ | 'CloseGame'
8
+ | 'LevelFinished'
9
+ | 'TaskFinished'
10
+ | 'LevelUpgrade'
11
+ | 'HistoryUserLevel'
12
+ | 'HistoryUserScore'
13
+ | 'UseGameItem'
14
+ | 'TaskEvent';
15
+ interface NativeMethodMap {
16
+ prefetchImages: (params: {
17
+ /** 需要预下载的图片 url */
18
+ images: string[];
19
+ }) => Promise<{
20
+ /** 错误消息 */
21
+ errMsg: string;
22
+ /** 错误码 */
23
+ errNo?: number;
24
+ }>;
25
+
26
+ showKeyboardSync: (params: {
27
+ /** 默认值 */
28
+ defaultValue?: string;
29
+ /** 最大长度 */
30
+ maxLength?: number; // Integer
31
+ /** 是否是多行 */
32
+ multiple?: boolean;
33
+ }) => {
34
+ /** 错误消息 */
35
+ errMsg: string;
36
+ /** 错误码 */
37
+ errNo?: number;
38
+ };
39
+
40
+ updateKeyboardSync: (params: {
41
+ /** 更新的文本内容 */
42
+ value?: string;
43
+ }) => Promise<{
44
+ /** 错误消息 */
45
+ errMsg: string;
46
+ /** 错误码 */
47
+ errNo?: number;
48
+ }>;
49
+
50
+ hideKeyboardSync: () => {
51
+ /** 错误消息 */
52
+ errMsg: string;
53
+ /** 错误码 */
54
+ errNo?: number;
55
+ };
56
+
57
+ /**
58
+ * 存储相关
59
+ */
60
+ getLocalStorageAsync: (params: { key: string }) => Promise<{
61
+ /** 错误消息 */
62
+ errMsg: string;
63
+ /** 错误码 */
64
+ errNo?: number;
65
+ data: {
66
+ /** 数据 */
67
+ data: any;
68
+ /** 数据类型 */
69
+ dataType: string;
70
+ };
71
+ }>;
72
+
73
+ setLocalStorageAsync: (params: { key: string; data: any; dataType: string }) => Promise<{
74
+ /** 错误消息 */
75
+ errMsg: string;
76
+ /** 错误码 */
77
+ errNo?: number;
78
+ }>;
79
+
80
+ removeLocalStorageAsync: (params: {
81
+ /** 要删除缓存数据的键 */
82
+ key: string;
83
+ }) => Promise<{
84
+ /** 错误消息 */
85
+ errMsg: string;
86
+ /** 错误码 */
87
+ errNo?: number;
88
+ }>;
89
+
90
+ clearLocalStorageAsync: () => Promise<{
91
+ /** 错误消息 */
92
+ errMsg: string;
93
+ /** 错误码 */
94
+ errNo?: number;
95
+ }>;
96
+
97
+ getStorageInfoAsync: () => Promise<{
98
+ /** 错误消息 */
99
+ errMsg: string;
100
+ /** 错误码 */
101
+ errNo?: number;
102
+ data: {
103
+ /** 当前已缓存数据的大小,单位:KB */
104
+ currentSize: number; // Long
105
+ /** 数据缓存大小上限,单位:KB */
106
+ limitSize: number; // Long
107
+ /** 已缓存数据的key */
108
+ keys: string[];
109
+ };
110
+ }>;
111
+
112
+ getStorageInfoSync: () => {
113
+ /** 错误消息 */
114
+ errMsg: string;
115
+ /** 错误码 */
116
+ errNo?: number;
117
+ data: {
118
+ /** 当前已缓存数据的大小,单位:KB */
119
+ currentSize: number; // Long
120
+ /** 数据缓存大小上限,单位:KB */
121
+ limitSize: number; // Long
122
+ /** 已缓存数据的key */
123
+ keys: string[];
124
+ };
125
+ };
126
+
127
+ exitAppAsync: () => Promise<{
128
+ /** 错误消息 */
129
+ errMsg: string;
130
+ /** 错误码 */
131
+ errNo?: number;
132
+ }>;
133
+
134
+ getSystemInfoSync: () => {
135
+ /** 错误消息 */
136
+ errMsg: string;
137
+ /** 错误码 */
138
+ errNo?: number;
139
+ data: ISystemInfo;
140
+ };
141
+
142
+ envSync: () => {
143
+ /** 错误消息 */
144
+ errMsg: string;
145
+ /** 错误码 */
146
+ errNo?: number;
147
+ /** 环境 */
148
+ data: Env;
149
+ };
150
+
151
+ loadScriptSync: () => {
152
+ /** 错误消息 */
153
+ errMsg: string;
154
+ /** 错误码 */
155
+ errNo?: number;
156
+ data: string;
157
+ };
158
+ /**
159
+ * 用户行为上报,
160
+ * TODO: 明确event类型和params类型
161
+ */
162
+ userTrackAsync: (params: { event: NativeTaskPointEvent; params: any; gameId: string }) => Promise<{
163
+ /** 错误消息 */
164
+ errMsg: string;
165
+ /** 错误码 */
166
+ errNo?: number;
167
+ }>;
168
+
169
+ trackAsync: (params: { event: string; data: any; webviewId?: number }) => Promise<{
170
+ /** 错误消息 */
171
+ errMsg: string;
172
+ /** 错误码 */
173
+ errNo?: number;
174
+ }>;
175
+
176
+ /**
177
+ * 网络请求
178
+ */
179
+ createRequestTaskSync: (params: {
180
+ url: string;
181
+ data: string | ArrayBuffer;
182
+ method: HTTPMethod;
183
+ header: {
184
+ 'content-type': string;
185
+ } & Record<string, string>;
186
+ enableCache: boolean;
187
+ responseType: string;
188
+ appendHostCookie: boolean;
189
+ }) => {
190
+ /** 错误消息 */
191
+ errMsg: string;
192
+ /** 错误码 */
193
+ errNo?: number;
194
+ data: {
195
+ requestTaskId?: string;
196
+ };
197
+ };
198
+
199
+ /**
200
+ * 登陆
201
+ */
202
+ loginSync: () => {
203
+ /** 错误消息 */
204
+ errMsg: string;
205
+ /** 错误码 */
206
+ errNo?: number;
207
+ data: {
208
+ uuid: string; // 用户唯一标识
209
+ };
210
+ };
211
+
212
+ /**
213
+ * 检查登陆状态
214
+ */
215
+ checkLoginAsync: () => Promise<{
216
+ /** 错误消息 */
217
+ errMsg: string;
218
+ /** 错误码 */
219
+ errNo?: number;
220
+ data: {
221
+ isLogin: boolean;
222
+ };
223
+ }>;
224
+
225
+ getUserInfoAsync: () => Promise<{
226
+ errNo?: number;
227
+ errMsg: string;
228
+ data: {
229
+ userInfo: {
230
+ avatarUrl?: string;
231
+ [key: string]: unknown;
232
+ }; // 用户信息对象,不包含 openid 等敏感信息
233
+ rawData: string; // 不包括敏感信息的原始数据字符串,用于计算签名。
234
+ signature?: string; // 使用 sha1( rawData + sessionkey ) 得到字符串
235
+ encryptedData?: string; // 包括敏感数据在内的完整用户信息的加密数据
236
+ iv?: string; // 加密算法的初始向量
237
+ realNameAuthenticationStatus?: 'uncertified' | 'certified';
238
+ };
239
+ }>;
240
+
241
+ getNetworkStatusSync: () => {
242
+ /** 错误消息 */
243
+ errMsg: string;
244
+ /** 错误码 */
245
+ errNo?: number;
246
+ data: {
247
+ isConnected: boolean;
248
+ networkType: 'wifi' | '4g' | '5g' | '3g' | '2g' | 'unknown';
249
+ };
250
+ };
251
+
252
+ updateContainerConfigSync: (params: { displayCapsuleButton: boolean; webviewId?: number }) => {
253
+ /** 错误消息 */
254
+ errMsg: string;
255
+ /** 错误码 */
256
+ errNo?: number;
257
+ };
258
+
259
+ openSchemaSync: (params: { schema: string }) => {
260
+ /** 错误消息 */
261
+ errMsg: string;
262
+ /** 错误码 */
263
+ errNo?: number;
264
+ };
265
+
266
+ openPageSync: (params: { url: string }) => {
267
+ /** 错误消息 */
268
+ errMsg: string;
269
+ /** 错误码 */
270
+ errNo?: number;
271
+ data?: {
272
+ webviewId: number;
273
+ };
274
+ };
275
+
276
+ closePageSync: (params: { webviewId: number }) => {
277
+ /** 错误消息 */
278
+ errMsg: string;
279
+ /** 错误码 */
280
+ errNo?: number;
281
+ };
282
+ }
283
+
284
+ interface NativeEventMap {
285
+ onMemoryWarning: [
286
+ {
287
+ /** 内存告警等级,只有 Android 才有,对应系统宏定义 */
288
+ level?: '5' | '10' | '15';
289
+ }
290
+ ];
291
+ onJoliboxEnterBackground: [];
292
+ onJoliboxEnterForeground: [];
293
+ onBeforeExit: [
294
+ {
295
+ uuid: string;
296
+ }
297
+ ];
298
+ onJoliboxServiceReady: [
299
+ {
300
+ runtimeInfo?: Env.hostUserInfo;
301
+ loadDuration?: number;
302
+ }
303
+ ];
304
+
305
+ onRequestTaskStateChange: [
306
+ {
307
+ requestTaskId: string;
308
+ state: string;
309
+ errMsg: string;
310
+ errNo?: number;
311
+ }
312
+ ];
313
+ onLoginStateChange: [
314
+ {
315
+ isLogin: boolean;
316
+ uuid: string;
317
+ token?: string;
318
+ }
319
+ ];
320
+ onInfoTapped: [
321
+ {
322
+ uuid: string;
323
+ }
324
+ ];
325
+ }
326
+ }
327
+ }
328
+
329
+ export {};
@@ -0,0 +1,30 @@
1
+ declare global {
2
+ namespace jsb.service {
3
+ /**
4
+ * implement 调 native 方法
5
+ */
6
+ type InvokeNative = <T extends keyof NativeMethodMap>(
7
+ method: T,
8
+ ...params: Parameters<NativeMethodMap[T]>
9
+ ) => ReturnType<NativeMethodMap[T]>;
10
+
11
+ type ApplyNative = <T extends keyof NativeMethodMap>(
12
+ method: T,
13
+ ...paras: Parameters<NativeMethodMap[T]>
14
+ ) => ApplyNativeReturn<ReturnType<NativeMethodMap[T]>>;
15
+
16
+ /**
17
+ * implement 监听 native 方法
18
+ */
19
+ type OnNative = <T extends keyof NativeEventMap>(
20
+ event: T,
21
+ handler: (...params: NativeEventMap[T]) => void
22
+ ) => void;
23
+
24
+ type OnNativeOnce = OnNative;
25
+
26
+ type OffNative = OnNative;
27
+ }
28
+ }
29
+
30
+ export {};
@@ -0,0 +1 @@
1
+ export declare function formatErrorCode(method: string, code?: number): string;
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@jolibox/native-bridge",
3
+ "description": "This project is Jolibox JS-SDk bridge for Native",
4
+ "version": "1.0.0",
5
+ "main": "dist/index.js",
6
+ "typings": "dist/index.d.ts",
7
+ "license": "MIT",
8
+ "files": [
9
+ "dist",
10
+ "src/types"
11
+ ],
12
+ "types": "./dist/index.d.ts",
13
+ "dependencies": {
14
+ "@jolibox/common": "1.1.13-beta.2",
15
+ "@jolibox/types": "1.1.13-beta.2"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "5.7.3",
19
+ "@types/jest": "28.1.1",
20
+ "rimraf": "6.0.1",
21
+ "esbuild": "0.24.2",
22
+ "@jolibox/eslint-config": "1.0.0"
23
+ },
24
+ "scripts": {
25
+ "clean": "rimraf ./dist",
26
+ "build": "npm run clean && npm run build:esm && tsc",
27
+ "build:esm": "BUILD_VERSION=$(node -p \"require('./package.json').version\") node esbuild.config.js --format=esm",
28
+ "build:iife": "BUILD_VERSION=$(node -p \"require('./package.json').version\") node esbuild.config.js --format=iife",
29
+ "build:cjs": "BUILD_VERSION=$(node -p \"require('./package.json').version\") node esbuild.config.js --format=cjs",
30
+ "dev": "tsc --watch",
31
+ "test": "jest"
32
+ },
33
+ "readme": "# Jolibox JSSDK Interface\n"
34
+ }
@@ -0,0 +1,27 @@
1
+ export declare global {
2
+ namespace jsb {
3
+ interface JSCore {
4
+ invoke: (method: string, params: string, callbackId: number) => string | Record<string, unknown> | void;
5
+
6
+ // publish: (event: string, data: Record<string, unknown>, webviewIds: number[]) => void;
7
+
8
+ // 安卓 Webview 没有call
9
+ call?: (
10
+ method: string,
11
+ params: Record<string, unknown>,
12
+ callbackId: number
13
+ ) => string | Record<string, unknown> | void;
14
+
15
+ onDocumentReady: (path: string) => void;
16
+ doExit: (uuid: string) => void;
17
+ bind?: (id: number, handler: (...args: unknown[]) => unknown) => void;
18
+ publish: (event: string, data: unknown, webviewIds: number[] | '*') => void;
19
+ }
20
+
21
+ type ApplyNativeReturn<T> = T extends Promise<infer U>
22
+ ? Promise<Omit<U, 'errMsg' | 'errNo'>>
23
+ : Omit<T, 'errMsg' | 'errNo'>;
24
+ }
25
+ }
26
+
27
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './native-method.d';
2
+ export * from './global.d';
3
+ export * from './native-method-map.d';
@@ -0,0 +1,329 @@
1
+ import { Env, ISystemInfo } from '@jolibox/types';
2
+
3
+ declare global {
4
+ namespace jsb.service {
5
+ type NativeTaskPointEvent =
6
+ | 'OpenGame'
7
+ | 'CloseGame'
8
+ | 'LevelFinished'
9
+ | 'TaskFinished'
10
+ | 'LevelUpgrade'
11
+ | 'HistoryUserLevel'
12
+ | 'HistoryUserScore'
13
+ | 'UseGameItem'
14
+ | 'TaskEvent';
15
+ interface NativeMethodMap {
16
+ prefetchImages: (params: {
17
+ /** 需要预下载的图片 url */
18
+ images: string[];
19
+ }) => Promise<{
20
+ /** 错误消息 */
21
+ errMsg: string;
22
+ /** 错误码 */
23
+ errNo?: number;
24
+ }>;
25
+
26
+ showKeyboardSync: (params: {
27
+ /** 默认值 */
28
+ defaultValue?: string;
29
+ /** 最大长度 */
30
+ maxLength?: number; // Integer
31
+ /** 是否是多行 */
32
+ multiple?: boolean;
33
+ }) => {
34
+ /** 错误消息 */
35
+ errMsg: string;
36
+ /** 错误码 */
37
+ errNo?: number;
38
+ };
39
+
40
+ updateKeyboardSync: (params: {
41
+ /** 更新的文本内容 */
42
+ value?: string;
43
+ }) => Promise<{
44
+ /** 错误消息 */
45
+ errMsg: string;
46
+ /** 错误码 */
47
+ errNo?: number;
48
+ }>;
49
+
50
+ hideKeyboardSync: () => {
51
+ /** 错误消息 */
52
+ errMsg: string;
53
+ /** 错误码 */
54
+ errNo?: number;
55
+ };
56
+
57
+ /**
58
+ * 存储相关
59
+ */
60
+ getLocalStorageAsync: (params: { key: string }) => Promise<{
61
+ /** 错误消息 */
62
+ errMsg: string;
63
+ /** 错误码 */
64
+ errNo?: number;
65
+ data: {
66
+ /** 数据 */
67
+ data: any;
68
+ /** 数据类型 */
69
+ dataType: string;
70
+ };
71
+ }>;
72
+
73
+ setLocalStorageAsync: (params: { key: string; data: any; dataType: string }) => Promise<{
74
+ /** 错误消息 */
75
+ errMsg: string;
76
+ /** 错误码 */
77
+ errNo?: number;
78
+ }>;
79
+
80
+ removeLocalStorageAsync: (params: {
81
+ /** 要删除缓存数据的键 */
82
+ key: string;
83
+ }) => Promise<{
84
+ /** 错误消息 */
85
+ errMsg: string;
86
+ /** 错误码 */
87
+ errNo?: number;
88
+ }>;
89
+
90
+ clearLocalStorageAsync: () => Promise<{
91
+ /** 错误消息 */
92
+ errMsg: string;
93
+ /** 错误码 */
94
+ errNo?: number;
95
+ }>;
96
+
97
+ getStorageInfoAsync: () => Promise<{
98
+ /** 错误消息 */
99
+ errMsg: string;
100
+ /** 错误码 */
101
+ errNo?: number;
102
+ data: {
103
+ /** 当前已缓存数据的大小,单位:KB */
104
+ currentSize: number; // Long
105
+ /** 数据缓存大小上限,单位:KB */
106
+ limitSize: number; // Long
107
+ /** 已缓存数据的key */
108
+ keys: string[];
109
+ };
110
+ }>;
111
+
112
+ getStorageInfoSync: () => {
113
+ /** 错误消息 */
114
+ errMsg: string;
115
+ /** 错误码 */
116
+ errNo?: number;
117
+ data: {
118
+ /** 当前已缓存数据的大小,单位:KB */
119
+ currentSize: number; // Long
120
+ /** 数据缓存大小上限,单位:KB */
121
+ limitSize: number; // Long
122
+ /** 已缓存数据的key */
123
+ keys: string[];
124
+ };
125
+ };
126
+
127
+ exitAppAsync: () => Promise<{
128
+ /** 错误消息 */
129
+ errMsg: string;
130
+ /** 错误码 */
131
+ errNo?: number;
132
+ }>;
133
+
134
+ getSystemInfoSync: () => {
135
+ /** 错误消息 */
136
+ errMsg: string;
137
+ /** 错误码 */
138
+ errNo?: number;
139
+ data: ISystemInfo;
140
+ };
141
+
142
+ envSync: () => {
143
+ /** 错误消息 */
144
+ errMsg: string;
145
+ /** 错误码 */
146
+ errNo?: number;
147
+ /** 环境 */
148
+ data: Env;
149
+ };
150
+
151
+ loadScriptSync: () => {
152
+ /** 错误消息 */
153
+ errMsg: string;
154
+ /** 错误码 */
155
+ errNo?: number;
156
+ data: string;
157
+ };
158
+ /**
159
+ * 用户行为上报,
160
+ * TODO: 明确event类型和params类型
161
+ */
162
+ userTrackAsync: (params: { event: NativeTaskPointEvent; params: any; gameId: string }) => Promise<{
163
+ /** 错误消息 */
164
+ errMsg: string;
165
+ /** 错误码 */
166
+ errNo?: number;
167
+ }>;
168
+
169
+ trackAsync: (params: { event: string; data: any; webviewId?: number }) => Promise<{
170
+ /** 错误消息 */
171
+ errMsg: string;
172
+ /** 错误码 */
173
+ errNo?: number;
174
+ }>;
175
+
176
+ /**
177
+ * 网络请求
178
+ */
179
+ createRequestTaskSync: (params: {
180
+ url: string;
181
+ data: string | ArrayBuffer;
182
+ method: HTTPMethod;
183
+ header: {
184
+ 'content-type': string;
185
+ } & Record<string, string>;
186
+ enableCache: boolean;
187
+ responseType: string;
188
+ appendHostCookie: boolean;
189
+ }) => {
190
+ /** 错误消息 */
191
+ errMsg: string;
192
+ /** 错误码 */
193
+ errNo?: number;
194
+ data: {
195
+ requestTaskId?: string;
196
+ };
197
+ };
198
+
199
+ /**
200
+ * 登陆
201
+ */
202
+ loginSync: () => {
203
+ /** 错误消息 */
204
+ errMsg: string;
205
+ /** 错误码 */
206
+ errNo?: number;
207
+ data: {
208
+ uuid: string; // 用户唯一标识
209
+ };
210
+ };
211
+
212
+ /**
213
+ * 检查登陆状态
214
+ */
215
+ checkLoginAsync: () => Promise<{
216
+ /** 错误消息 */
217
+ errMsg: string;
218
+ /** 错误码 */
219
+ errNo?: number;
220
+ data: {
221
+ isLogin: boolean;
222
+ };
223
+ }>;
224
+
225
+ getUserInfoAsync: () => Promise<{
226
+ errNo?: number;
227
+ errMsg: string;
228
+ data: {
229
+ userInfo: {
230
+ avatarUrl?: string;
231
+ [key: string]: unknown;
232
+ }; // 用户信息对象,不包含 openid 等敏感信息
233
+ rawData: string; // 不包括敏感信息的原始数据字符串,用于计算签名。
234
+ signature?: string; // 使用 sha1( rawData + sessionkey ) 得到字符串
235
+ encryptedData?: string; // 包括敏感数据在内的完整用户信息的加密数据
236
+ iv?: string; // 加密算法的初始向量
237
+ realNameAuthenticationStatus?: 'uncertified' | 'certified';
238
+ };
239
+ }>;
240
+
241
+ getNetworkStatusSync: () => {
242
+ /** 错误消息 */
243
+ errMsg: string;
244
+ /** 错误码 */
245
+ errNo?: number;
246
+ data: {
247
+ isConnected: boolean;
248
+ networkType: 'wifi' | '4g' | '5g' | '3g' | '2g' | 'unknown';
249
+ };
250
+ };
251
+
252
+ updateContainerConfigSync: (params: { displayCapsuleButton: boolean; webviewId?: number }) => {
253
+ /** 错误消息 */
254
+ errMsg: string;
255
+ /** 错误码 */
256
+ errNo?: number;
257
+ };
258
+
259
+ openSchemaSync: (params: { schema: string }) => {
260
+ /** 错误消息 */
261
+ errMsg: string;
262
+ /** 错误码 */
263
+ errNo?: number;
264
+ };
265
+
266
+ openPageSync: (params: { url: string }) => {
267
+ /** 错误消息 */
268
+ errMsg: string;
269
+ /** 错误码 */
270
+ errNo?: number;
271
+ data?: {
272
+ webviewId: number;
273
+ };
274
+ };
275
+
276
+ closePageSync: (params: { webviewId: number }) => {
277
+ /** 错误消息 */
278
+ errMsg: string;
279
+ /** 错误码 */
280
+ errNo?: number;
281
+ };
282
+ }
283
+
284
+ interface NativeEventMap {
285
+ onMemoryWarning: [
286
+ {
287
+ /** 内存告警等级,只有 Android 才有,对应系统宏定义 */
288
+ level?: '5' | '10' | '15';
289
+ }
290
+ ];
291
+ onJoliboxEnterBackground: [];
292
+ onJoliboxEnterForeground: [];
293
+ onBeforeExit: [
294
+ {
295
+ uuid: string;
296
+ }
297
+ ];
298
+ onJoliboxServiceReady: [
299
+ {
300
+ runtimeInfo?: Env.hostUserInfo;
301
+ loadDuration?: number;
302
+ }
303
+ ];
304
+
305
+ onRequestTaskStateChange: [
306
+ {
307
+ requestTaskId: string;
308
+ state: string;
309
+ errMsg: string;
310
+ errNo?: number;
311
+ }
312
+ ];
313
+ onLoginStateChange: [
314
+ {
315
+ isLogin: boolean;
316
+ uuid: string;
317
+ token?: string;
318
+ }
319
+ ];
320
+ onInfoTapped: [
321
+ {
322
+ uuid: string;
323
+ }
324
+ ];
325
+ }
326
+ }
327
+ }
328
+
329
+ export {};
@@ -0,0 +1,30 @@
1
+ declare global {
2
+ namespace jsb.service {
3
+ /**
4
+ * implement 调 native 方法
5
+ */
6
+ type InvokeNative = <T extends keyof NativeMethodMap>(
7
+ method: T,
8
+ ...params: Parameters<NativeMethodMap[T]>
9
+ ) => ReturnType<NativeMethodMap[T]>;
10
+
11
+ type ApplyNative = <T extends keyof NativeMethodMap>(
12
+ method: T,
13
+ ...paras: Parameters<NativeMethodMap[T]>
14
+ ) => ApplyNativeReturn<ReturnType<NativeMethodMap[T]>>;
15
+
16
+ /**
17
+ * implement 监听 native 方法
18
+ */
19
+ type OnNative = <T extends keyof NativeEventMap>(
20
+ event: T,
21
+ handler: (...params: NativeEventMap[T]) => void
22
+ ) => void;
23
+
24
+ type OnNativeOnce = OnNative;
25
+
26
+ type OffNative = OnNative;
27
+ }
28
+ }
29
+
30
+ export {};