@jolibox/sdk 0.0.8 → 1.0.0-beta.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.
Files changed (83) hide show
  1. package/.eslintrc.js +3 -0
  2. package/.rush/temp/package-deps_build.json +28 -0
  3. package/.rush/temp/shrinkwrap-deps.json +76 -0
  4. package/README.md +1 -91
  5. package/dist/api/__tests__/canIUse.test.d.ts +1 -0
  6. package/dist/api/can-i-use.d.ts +1 -0
  7. package/dist/api/get-system-info.d.ts +3 -0
  8. package/dist/api/index.d.ts +2 -0
  9. package/dist/errors.d.ts +2 -0
  10. package/dist/index.cjs.js +1 -0
  11. package/dist/index.d.ts +19 -309
  12. package/dist/index.es.js +1 -0
  13. package/dist/loader/h5.d.ts +6 -0
  14. package/dist/loader/index.d.ts +16 -0
  15. package/dist/loader/native.d.ts +6 -0
  16. package/dist/loader/version.d.ts +2 -0
  17. package/dist/sdks/ads.d.ts +11 -0
  18. package/dist/sdks/keyboard.d.ts +34 -0
  19. package/dist/sdks/lifecycle.d.ts +16 -0
  20. package/dist/sdks/runtime.d.ts +1 -0
  21. package/dist/sdks/sdk.d.ts +11 -0
  22. package/dist/sdks/storage.d.ts +8 -0
  23. package/dist/utils/can-i-use.d.ts +2 -0
  24. package/dist/utils/report.d.ts +3 -0
  25. package/package.json +22 -32
  26. package/sdk.build.log +13 -0
  27. package/src/api/__tests__/canIUse.test.ts +76 -0
  28. package/src/api/can-i-use.ts +38 -0
  29. package/src/api/get-system-info.ts +14 -0
  30. package/src/api/index.ts +2 -0
  31. package/src/errors.ts +42 -0
  32. package/src/index.ts +29 -0
  33. package/src/loader/h5.ts +175 -0
  34. package/src/loader/index.ts +65 -0
  35. package/src/loader/native.ts +62 -0
  36. package/src/loader/version.ts +44 -0
  37. package/src/sdks/ads.ts +32 -0
  38. package/src/sdks/keyboard.ts +50 -0
  39. package/src/sdks/lifecycle.ts +32 -0
  40. package/src/sdks/runtime.ts +3 -0
  41. package/src/sdks/sdk.ts +22 -0
  42. package/src/sdks/storage.ts +35 -0
  43. package/src/utils/can-i-use.ts +24 -0
  44. package/src/utils/report.ts +23 -0
  45. package/tsconfig.json +12 -107
  46. package/README-zh_cn.md +0 -91
  47. package/dist/index.cjs +0 -2
  48. package/dist/index.cjs.map +0 -1
  49. package/dist/index.d.cts +0 -314
  50. package/dist/index.iife.js +0 -2
  51. package/dist/index.iife.js.map +0 -1
  52. package/dist/index.js +0 -2
  53. package/dist/index.js.map +0 -1
  54. package/docs/.nojekyll +0 -1
  55. package/docs/assets/highlight.css +0 -106
  56. package/docs/assets/icons.js +0 -18
  57. package/docs/assets/icons.svg +0 -1
  58. package/docs/assets/main.js +0 -60
  59. package/docs/assets/navigation.js +0 -1
  60. package/docs/assets/search.js +0 -1
  61. package/docs/assets/style.css +0 -1493
  62. package/docs/classes/index.JoliboxAds.html +0 -41
  63. package/docs/classes/index.JoliboxRuntime.html +0 -8
  64. package/docs/classes/index.JoliboxSDK.html +0 -4
  65. package/docs/documents/README.html +0 -39
  66. package/docs/enums/index.JoliboxRuntimeEvents.html +0 -7
  67. package/docs/index.html +0 -39
  68. package/docs/interfaces/index.IAdConfigParams.html +0 -12
  69. package/docs/interfaces/index.IAdUnitParams.html +0 -11
  70. package/docs/interfaces/index.IAdsInitParams.html +0 -5
  71. package/docs/interfaces/index.IInterstitialsParams.html +0 -15
  72. package/docs/interfaces/index.IJoliboxConfig.html +0 -3
  73. package/docs/interfaces/index.IJoliboxSDKLoaderConfig.html +0 -3
  74. package/docs/interfaces/index.IPlacementInfo.html +0 -59
  75. package/docs/interfaces/index.IPrerollParams.html +0 -6
  76. package/docs/interfaces/index.IRewardParams.html +0 -18
  77. package/docs/interfaces/index.IVersionMetadata.html +0 -4
  78. package/docs/modules/index.html +0 -18
  79. package/docs/modules.html +0 -3
  80. package/docs/types/index.AdUnitFormat.html +0 -2
  81. package/docs/types/index.IAdBreakParams.html +0 -2
  82. package/tsup.config.ts +0 -27
  83. package/typedoc.config.mjs +0 -17
@@ -0,0 +1 @@
1
+ var W=Object.defineProperty,Ie=Object.getOwnPropertyDescriptor,Ue=(e,t)=>{for(var r in t)W(e,r,{get:t[r],enumerable:!0})},Q=(e,t,r,n)=>{for(var s=n>1?void 0:n?Ie(t,r):t,o=e.length-1,i;o>=0;o--)(i=e[o])&&(s=(n?i(t,r,s):i(s))||s);return n&&s&&W(t,r,s),s};function Ae(e){return new Promise(t=>{setTimeout(()=>{t()},e)})}function k(e){return typeof e=="string"}function Y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&!(e instanceof RegExp)&&!(e instanceof Date)}function Le(e){return typeof e>"u"}function we(e){return Le(e)||e===null}function Ce(e){return typeof e=="function"}function X(e){let t=e,r=null,n=function(...s){return r||(r=new t(...s)),r};return n.prototype=t.prototype,n}var Te=(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))(Te||{}),De=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}},q=class extends De{constructor(){super(...arguments),this.kind="INTERNAL_ERROR"}};var Z=class extends q{constructor(){super(...arguments),this.name="INTERNAL_JS_MODULE_FETCH_ERROR",this.priority="P0"}},y=class extends q{constructor(){super(...arguments),this.name="INTERNAL_JS_MODULE_EVAL_ERROR",this.priority="P0"}};function R(e){return(...t)=>{(globalThis.VConsole?.[e]??globalThis.console[e])(...t)}}var Oe={log:R("log"),warn:R("warn"),info:R("info"),error:R("error"),debug:R("debug")};Object.assign(globalThis,{logger:Oe});var ee=Symbol.for("Jolibox.canIUseMap"),Ne={};globalThis[ee]=Ne;var te={get config(){return globalThis[ee]}};function j(e,t,r){let n=0;if(e!==t){let s=e.split("."),o=t.split("."),i=Math.max(s.length,o.length);for(let l=0;l<i;l++){let _=parseInt(s[l],10)||0,c=parseInt(o[l],10)||0;if(_>c){n=1;break}else if(_<c){n=-1;break}}}if(!r)return n;switch(r){case">":return n>0;case"<":return n<0;case"=":return n===0;case">=":return n>=0;case"<=":return n<=0;default:return!1}}var a=class U{static{this.Undefined=new U(void 0)}constructor(t){this.element=t,this.next=U.Undefined,this.prev=U.Undefined}},Ke=class{constructor(){this._first=a.Undefined,this._last=a.Undefined,this._size=0}get size(){return this._size}isEmpty(){return this._first===a.Undefined}clear(){let e=this._first;for(;e!==a.Undefined;){let t=e.next;e.prev=a.Undefined,e.next=a.Undefined,e=t}this._first=a.Undefined,this._last=a.Undefined,this._size=0}unshift(e){return this._insert(e,!1)}push(e){return this._insert(e,!0)}_insert(e,t){let r=new a(e);if(this._first===a.Undefined)this._first=r,this._last=r;else if(t){let s=this._last;this._last=r,r.prev=s,s.next=r}else{let s=this._first;this._first=r,r.next=s,s.prev=r}this._size+=1;let n=!1;return()=>{n||(n=!0,this._remove(r))}}shift(){if(this._first!==a.Undefined){let e=this._first.element;return this._remove(this._first),e}}pop(){if(this._last!==a.Undefined){let e=this._last.element;return this._remove(this._last),e}}_remove(e){if(e.prev!==a.Undefined&&e.next!==a.Undefined){let t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===a.Undefined&&e.next===a.Undefined?(this._first=a.Undefined,this._last=a.Undefined):e.next===a.Undefined?(this._last=this._last.prev,this._last.next=a.Undefined):e.prev===a.Undefined&&(this._first=this._first.next,this._first.prev=a.Undefined);this._size-=1}*[Symbol.iterator](){let e=this._first;for(;e!==a.Undefined;)yield e.element,e=e.next}},Pe=0,I=class{constructor(e){this.value=e,this.id=Pe++}},v=class{constructor(e){this.options=e,this._size=0}dispose(e){this._disposed||(this._disposed=!0,this._listeners&&(e?(this._listeners instanceof I&&(this._listeners=[this._listeners]),this._listeners=this._listeners.filter(t=>t?.value===e)):(this._listeners=void 0,this._size=0)),this.options?.onDidRemoveLastListener?.())}get event(){return this._event??=(e,t)=>{if(this._disposed)return()=>{console.info("[Jolibox SDK] Emitter is _disposed")};t&&(e=e.bind(t));let r=new I(e);this._listeners?this._listeners instanceof I?this._listeners=[this._listeners,r]:this._listeners.push(r):(this.options?.onWillAddFirstListener?.(this),this._listeners=r,this.options?.onDidFirstListener?.(this)),this.options?.onDidAddListener?.(this),this._size++},this._event}_deliver(e,t){if(!e)return;let r=this.options?.onListenerError||Error.constructor;if(!r){e.value(t);return}try{e.value(t)}catch(n){r(n)}}fire(e){this._listeners&&(this._listeners instanceof I?this._deliver(this._listeners,e):this._listeners.forEach(t=>this._deliver(t,e)))}hasListeners(){return this._size>0}},J=class{constructor(){this.listeners=new Map,this.listerHandlerMap=new WeakMap,this.cachedEventQueue=new Map}on(e,t){let r=this.listeners.get(e)??new v,n=o=>t(...o.args);this.listerHandlerMap.set(t,n),r.event(n),this.listeners.set(e,r);let s=this.cachedEventQueue.get(e);if(s)for(;s.size>0;)r.fire({event:e,...s.shift()})}off(e,t){let r=this.listeners.get(e);if(r){let n=this.listerHandlerMap.get(t);r.dispose(n)}}emit(e,...t){let r=this.listeners.get(e);if(r)r.fire({event:e,args:t});else{let n=this.cachedEventQueue.get(e);n||(n=new Ke,this.cachedEventQueue.set(e,n)),n.push({args:t})}}},P={};Ue(P,{None:()=>Me,filter:()=>je,once:()=>re,toPromise:()=>ke});var Me=()=>{console.log("[Jolibox SDK] None Event")};function ke(e){return new Promise(t=>re(e)(t))}function re(e){return(t,r=null)=>{let n=!1;return e(s=>{if(!n)return n=!0,t.call(r,s)},null)}}function je(e,t){return(r=>{let n,s={onWillAddFirstListener(){n=r(o.fire,o)}},o=new v(s);return o.event})((r,n=null)=>e(s=>t(s)&&r.call(n,s),null))}var N=Symbol.for("Jolibox.hostEmitter"),Je=()=>{let e=new J;return globalThis[N]||(globalThis[N]={on:e.on.bind(e),off:e.off.bind(e),emit:e.emit.bind(e)}),globalThis[N]},ne=Je();function Fe(e,t){let r=Math.min(e.length,t.length);for(let n=0;n<r;n++)Be(e[n],t[n])}function Be(e,t){if(k(t)){if(typeof e!==t)throw new Error(`argument does not match constraint: typeof ${t}`)}else if(Ce(t)){try{if(e instanceof t)return}catch{}if(!we(e)&&e.constructor===t||t.length===1&&t.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 A=class{constructor(){this._commands=new Map,this._onDidRegisterCommand=new v,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 r=[];for(let s of e.metadata.args)r.push(s.constraint);let n=e.handler;e.handler=function(...s){return Fe(s,r),n(...s)}}let{id:t}=e;this._commands.get(t)&&console.info(`[Jolibox SDK] duplicated command is registered ${t}`),this._commands.set(t,e),this._onDidRegisterCommand.fire(t)}getCommand(e){return this._commands.get(e)}getCommands(){let e=new Map;for(let t of this._commands.keys()){let r=this.getCommand(t);r&&e.set(t,r)}return e}};A=Q([X],A);var M=class{constructor(){this._onWillExecuteCommand=new v,this.onWillExecuteCommand=this._onWillExecuteCommand.event,this._onDidExecuteCommand=new v,this.onDidExecuteCommand=this._onDidExecuteCommand.event,this.registry=new A,this._starActivation=null}_activateStar(){return this._starActivation||(this._starActivation=Ae(3e4)),this._starActivation}async executeCommand(e,...t){return this.registry.getCommand(e)?this._tryExecuteCommand(e,t):(await Promise.all([Promise.race([this._activateStar(),P.toPromise(P.filter(this.registry.onDidRegisterCommand,r=>r===e))])]),this._tryExecuteCommand(e,t))}executeCommandThowErr(e,...t){if(!this.registry.getCommand(e))throw new Error(`command '${e}' not found`);let r=this.registry.getCommand(e);this._onWillExecuteCommand.fire({commandId:e,args:t});let n=this.invokeFunction(r.handler,...t);return this._onDidExecuteCommand.fire({commandId:e,args:t}),n}_tryExecuteCommand(e,t){let r=this.registry.getCommand(e);if(!r)return Promise.reject(new Error(`command '${e}' not found`));try{this._onWillExecuteCommand.fire({commandId:e,args:t});let n=this.invokeFunction(r.handler,...t);return this._onDidExecuteCommand.fire({commandId:e,args:t}),Promise.resolve(n)}catch(n){return Promise.reject(n)}}invokeFunction(e,...t){let r=!1;try{return e(...t)}finally{r=!0}}};M=Q([X],M);var K=Symbol.for("Jolibox.commands");function h(){if(globalThis[K])return globalThis[K];let e=new A,t=new M,r={registerCommand(n,s,o){e.registerCommand({id:n,handler:s,metadata:o})},executeCommand(n,...s){return t.executeCommand(n,...s)},excuteCommandSync(n,...s){return t.executeCommandThowErr(n,...s)}};return globalThis[K]=r,r}document.addEventListener("DOMContentLoaded",()=>ne.emit("onDocumentReady"));var se=h(),F=e=>{se.executeCommand("ReportSDK.traceSystem",{event:"global_js_error",info:{err:JSON.stringify(e)}}).catch(t=>{console.error(`Fallback report: ${t} ${JSON.stringify(e)}`)})},g=F;window.addEventListener("unhandledrejection",F.bind(void 0));window.addEventListener("error",F.bind(void 0));window.onerror=(e,t,r,n,s)=>{se.executeCommand("ReportSDK.traceSystem",{event:"global_js_error",info:{err:JSON.stringify({message:e,source:t,lineno:r,colno:n,error:s})}}).catch(o=>{console.error(`Fallback report: ${o} ${JSON.stringify(e)}`)})};var B=e=>{let t=e.split("-")[1];t&&(e=e.replace(`-${t}`,""));let r=e.split("+")[1];r&&(e=e.replace(`+${r}`,""));let n=e.split(".").slice(0,3),[s,o,i]=[n[0]??"0",n[1]??"0",n[2]??"0"];return{major:s,minor:o,patch:i,prerelease:t,build:r}},S=e=>parseInt(B(e).major,10),b=(e,t)=>{let{major:r,minor:n,patch:s}=B(e),{major:o,minor:i,patch:l}=B(t);return r!==o?r>o?1:-1:n!==i?n>i?1:-1:s!==l?s>l?1:-1:0};var oe=h(),L=(e,t)=>{oe.executeCommand("ReportSDK.traceSystem",{event:e,info:t})},E=(e,t,r)=>{oe.executeCommand("ReportSDK.traceSystemTimeline",{event:e,duration:t,extra:r})};var ce="jolibox-sdk-loadermeta",x=JSON.parse(localStorage.getItem(ce)??"{}"),V=Date.now(),ie=(e,t)=>e>t&&Math.abs(e-t)/(1e3*60*60*24)>=7,ae=e=>!/^(Failed to fetch version|Couldn't find the requested file)/.test(e);async function Ve(){let e="https://stg-api.jolibox.com/api/fe-configs/js-sdk/version_metadata";try{let t=await fetch(e,{method:"GET",headers:{"Content-Type":"application/json"}}),{implement_version:r,bootstrap_version:n}=await t.json(),s={...x,timestamp:V};if(n){let{bootstrap_version:o}=x;if(!(o&&b(o,n))){let i=await(await fetch(G(n))).text();ae(i)&&(s={...s,bootstrap_version:n,bootstrap_script:i})}}if(r){let{implement_version:o}=x;if(!(o&&b(o,r))){let i=await(await fetch($(r))).text();ae(i)&&(s={...s,implement_version:r,implement_script:i})}}localStorage.setItem(ce,JSON.stringify(s))}catch(t){console.warn("Failed to fetch loader metadata: ",t)}}var me=e=>{let{currentMajorVersion:t,currentVersion:r,bootstrapUrl:n,implementUrl:s}=e;function o(){let{bootstrap_version:c,bootstrap_script:p,timestamp:d}=x;if(c&&p&&d&&!ie(V,d)&&S(c)==t&&b(c,r)>0)return{script:p,type:"localscript"};try{let m=new XMLHttpRequest;return m.open("GET",n,!1),m.send(),{script:m.responseText,type:"fetch_from_cdn"}}catch(m){g(new Z(`Bootstrap module faile to fetch ${m}`))}}function i(){let c=Date.now();L("js_sdk_begin",{t:c});let{script:p,type:d}=o()??{};if(p){let m=document.createElement("script");m.type="text/javascript",m.innerHTML=p,document.head.appendChild(m),E("bootstrapModuleLoaded",Date.now()-c,{type:d})}}function l(c){(async d=>{try{let m=new Blob([d],{type:"application/javascript"}),f=URL.createObjectURL(m),xe=await import(f);return URL.revokeObjectURL(f),xe}catch(m){g(new y(`implement module evaluate error in h5:${m} `))}})(c)}function _(){let c=Date.now(),{implement_script:p,implement_version:d,timestamp:m}=x;if(p&&d&&m&&!ie(V,m)&&S(d)==t&&b(d,r)>0){l(p),E("implementModuleLoaded",Date.now()-c,{type:"loadscript"});return}let f=document.createElement("script");f.type="module",f.crossOrigin="anonymous",f.src=s,f.onload=()=>{E("bootstrapModuleLoaded",Date.now()-c,{type:"fetch_from_cdn"})},document.head.appendChild(f)}return()=>{try{i(),_(),Ve()}catch(c){g(new y(`module evaluate error: ${c}`))}}};var le=(e,t)=>{let r=s=>{let o=e({path:s});if(!o)throw`module ${s} load failed ${o}`;return o};function n(s){(async i=>{try{let l=new Blob([i],{type:"application/javascript"}),_=URL.createObjectURL(l),c=await import(_);return URL.revokeObjectURL(_),c}catch(l){g(new y(`implement module evaluate error in native:${l} `))}})(s)}return()=>{try{let s=Date.now();L("js_sdk_begin",{t:s});let o=r(t.bootstrapUrl),i=document.createElement("script");i.type="text/javascript",i.innerHTML=o,document.head.appendChild(i),E("implementModuleLoaded",Date.now()-s,{type:"native"});let l=r(t.implementUrl);n(l),E("bootstrapModuleLoaded",Date.now()-s,{type:"native"})}catch(s){console.error(`native load script error: ${s}`),g(new y(`module load failed ${s}`))}}};var Ge="1.0.0",pe=Ge,H=S(pe),fe=window.webkit?e=>window.prompt("loadScript",JSON.stringify(e)):void 0,$e=typeof fe<"u",G=e=>`http://cdn.jsdelivr.net/npm/@jolibox/bootstrap@${e}/dist/index.js`,$=e=>`http://cdn.jsdelivr.net/npm/@jolibox/implement@${e}/dist/index.js`,de=G(H),ue=$(H);function He(){$e?le(fe,{bootstrapUrl:de,implementUrl:ue})():me({bootstrapUrl:de,implementUrl:ue,currentMajorVersion:H,currentVersion:pe})()}He();var z=h();async function he(){return await z.executeCommand("API.getSystemInfo")}function _e(){return z.excuteCommandSync("API.getSystemInfoSync")}function ge(){return z.excuteCommandSync("API.env")}function Ee(e,t){return te.config[e]?.[t]}function ye(e,t,r){let n=Array.isArray(t)?t:t.replace(/\[(\d+)\]/g,".$1").split("."),s=e;for(let o of n)if(s&&(typeof s=="object"||Array.isArray(s)))s=s[o];else return r;return s===void 0?r:s}var ve="1.0.0";function w(e){let r=ge().data?.deviceInfo?.platform;if(!r)return!1;let[n,...s]=e.split(":"),o=Ee(r=="h5"?r:"native",n);if(!o)return!1;let i=o.version;return typeof i!="string"||j(ve,i,"<")?!1:s.length===0?!0:Re(o,s)||Re(o.properties,s)}function Re(e,t){if(!e)return!1;let r=ye(e,t);return r?Y(r)?!0:k(r)?j(ve,r,">="):!1:!1}var Se=window.JoliboxRuntime;var u=class{constructor(){this.commands=h();this._emitter=new J}addEventListener(t,r){this._emitter.on(t,(...n)=>r(n[0]))}triggerEvent(t,r){this._emitter.emit(t,r)}canUse(t){return w(t)}};var ze="LifecycleSDK.onReady",C=class extends u{constructor(){super()}onReady(t){let r=n=>{t.call(this,n),this.triggerEvent(ze,n)};this.commands.executeCommand("LifecycleSDK.onReady",r.bind(this))}exitGame(t){this.commands.executeCommand("LifecycleSDK.exitGame",t.onBeforeExit)}onGameHide(t){this.commands.executeCommand("LifecycleSDK.onGameHide",t.bind(this))}onGameShow(t){this.commands.executeCommand("LifecycleSDK.onGameShow",t.bind(this))}};var T=class extends u{async getItem(t){return await this.commands.executeCommand("StorageSDK.getItem",t)}async setItem(t,r){if(t.length>128)return{code:"PARAMETER_ERROR",message:"[SDK] cloud storage setItem error: length of key should be less than 128"};let n=typeof r=="string"?r:String(r);return t.length+n.length>1024?{code:"PARAMETER_ERROR",message:"[SDK] cloud storage setItem error: length of key and value should be less than 1024"}:await this.commands.executeCommand("StorageSDK.setItem",t,r)}async removeItem(t){return this.commands.executeCommand("StorageSDK.removeItem",t)}async clear(){return this.commands.executeCommand("StorageSDK.clear")}};var D=class extends u{constructor(){super();this.init=r=>{this.commands.executeCommand("AdsSDK.init",r)};this.adConfig=r=>{this.commands.executeCommand("AdsSDK.adConfig",r)};this.adBreak=r=>{this.commands.executeCommand("AdsSDK.adBreak",r)};this.adUnit=r=>{this.commands.executeCommand("AdsSDK.adUnit",r)}}};var O=class extends u{showKeyboard(t){if(!this.canUse("keyboard.showKeyboard"))return{code:"FAILURE",message:"[Jolibox SDK] keyboard.showKeyboard is not supported in this platform"};this.commands.executeCommand("KeyboardSDK.showKeyboard",t)}updateKeyboard(t){if(!this.canUse("keyboard.updateKeyboard"))return{code:"FAILURE",message:"[Jolibox SDK] keyboard.updateKeyboard is not supported in this platform"};this.commands.executeCommand("KeyboardSDK.updateKeyboard",t)}hideKeyboard(){if(!this.canUse("keyboard.hideKeyboard"))return{code:"FAILURE",message:"[Jolibox SDK] keyboard.hideKeyboard is not supported in this platform"};this.commands.executeCommand("KeyboardSDK.hideKeyboard")}};var be=class{constructor(){this.runtime=new Se;this.ads=new D;this.lifecycle=new C;this.storage=new T;this.keyboard=new O;this.getSystemInfo=he.bind(this);this.getSystemInfoSync=_e.bind(this);this.canIUse=w.bind(this)}};export{be as JoliboxSDK};
@@ -0,0 +1,6 @@
1
+ export declare const createLoadImplement: (params: {
2
+ currentVersion: string;
3
+ currentMajorVersion: number;
4
+ bootstrapUrl: string;
5
+ implementUrl: string;
6
+ }) => () => void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Due to security restrictions on iOS, dynamically loading script tags is not supported.
3
+ * Therefore, a loadScript method needs to be injected on the client side to implement evalJavascriptFun.
4
+ * Link:https://mabin004.github.io/2018/06/25/iOS%E5%BA%94%E7%94%A8%E6%B2%99%E7%AE%B1/
5
+ */
6
+ declare global {
7
+ interface Window {
8
+ webkit?: unknown;
9
+ }
10
+ }
11
+ /**
12
+ * Do not expose the logic of dynamically retrieving URL information in the config,
13
+ * as this logic needs to remain self-contained within the SDK.
14
+ */
15
+ export declare const getBoostrapModuleUrl: (version: string | number) => string;
16
+ export declare const getImplementModuleUrl: (version: string | number) => string;
@@ -0,0 +1,6 @@
1
+ export declare const createLoadImplement: (loadScript: (params: {
2
+ path: string;
3
+ }) => string | null, params: {
4
+ bootstrapUrl: string;
5
+ implementUrl: string;
6
+ }) => () => void;
@@ -0,0 +1,2 @@
1
+ export declare const major: (version: string) => number;
2
+ export declare const compare: (v1: string, v2: string) => -1 | 0 | 1;
@@ -0,0 +1,11 @@
1
+ import type { IAdBreakParams, IAdConfigParams, IAdsInitParams, IAdUnitParams, JoliboxAds as IJoliboxAds } from '@jolibox/types/dist/sdks/ads';
2
+ import { BaseSDK, BaseSDKEventMap } from './sdk';
3
+ type JoliboxAdsEventMap = BaseSDKEventMap;
4
+ export declare class JoliboxAds extends BaseSDK<JoliboxAdsEventMap> implements IJoliboxAds {
5
+ constructor();
6
+ init: (config?: IAdsInitParams) => void;
7
+ adConfig: (params: IAdConfigParams) => void;
8
+ adBreak: (params: IAdBreakParams) => void;
9
+ adUnit: (params: IAdUnitParams) => void;
10
+ }
11
+ export {};
@@ -0,0 +1,34 @@
1
+ import { BaseSDK } from './sdk';
2
+ import { Keyboard, ResponseType } from '@jolibox/types';
3
+ export declare class KeyboardSDK extends BaseSDK implements Keyboard {
4
+ /**
5
+ * 显示键盘
6
+ * @param params
7
+ * @returns
8
+ */
9
+ showKeyboard(params: {
10
+ defaultValue?: string;
11
+ maxLength?: number;
12
+ multiple?: boolean;
13
+ }): {
14
+ code: ResponseType;
15
+ message: string;
16
+ } | undefined;
17
+ /**
18
+ * 更新键盘
19
+ * @param value
20
+ * @returns
21
+ */
22
+ updateKeyboard(value: string): {
23
+ code: ResponseType;
24
+ message: string;
25
+ } | undefined;
26
+ /**
27
+ * 隐藏键盘
28
+ * @returns
29
+ */
30
+ hideKeyboard(): {
31
+ code: ResponseType;
32
+ message: string;
33
+ } | undefined;
34
+ }
@@ -0,0 +1,16 @@
1
+ import { Env, Lifecycle } from '@jolibox/types';
2
+ import { BaseSDK, BaseSDKEventMap } from './sdk';
3
+ declare const LIFECYCLE_ON_READY = "LifecycleSDK.onReady";
4
+ interface LifecycleSDKEventMap extends BaseSDKEventMap {
5
+ [LIFECYCLE_ON_READY]: Env['hostUserInfo'] | undefined;
6
+ }
7
+ export declare class LifecycleSDK extends BaseSDK<LifecycleSDKEventMap> implements Lifecycle {
8
+ constructor();
9
+ onReady(callback: (info?: Env['hostUserInfo']) => void): void;
10
+ exitGame(params: {
11
+ onBeforeExit: () => void;
12
+ }): void;
13
+ onGameHide(params: () => void): void;
14
+ onGameShow(params: () => void): void;
15
+ }
16
+ export {};
@@ -0,0 +1 @@
1
+ export declare const RuntimeSDK: any;
@@ -0,0 +1,11 @@
1
+ import { EventEmitter } from '@jolibox/common';
2
+ export interface BaseSDKEventMap {
3
+ _baseSDKMarker?: never;
4
+ }
5
+ export declare abstract class BaseSDK<T = BaseSDKEventMap> {
6
+ readonly commands: import("@jolibox/common").Commands;
7
+ readonly _emitter: EventEmitter<Record<string, unknown[]>, string>;
8
+ addEventListener<K extends keyof T & string>(event: K, callback: (data: T[K]) => void): void;
9
+ triggerEvent<K extends keyof T & string>(event: K, params: T[K]): void;
10
+ canUse(command: string): boolean;
11
+ }
@@ -0,0 +1,8 @@
1
+ import { BaseSDK } from './sdk';
2
+ import { StandardResponse, Storage } from '@jolibox/types';
3
+ export declare class StorageSDK extends BaseSDK implements Storage {
4
+ getItem(key: string): Promise<StandardResponse<string | null>>;
5
+ setItem(key: string, value: number | string | boolean): Promise<StandardResponse<void>>;
6
+ removeItem(key: string): Promise<StandardResponse<void>>;
7
+ clear(): Promise<StandardResponse<void>>;
8
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getCanIUseConfig(platform: 'h5' | 'native', key: string): import("@jolibox/common").CanIUseInfo | undefined;
2
+ export declare function get<T extends Record<string, any>, P extends string | string[], Default = undefined>(obj: T, path: P, defaultValue?: Default): unknown;
@@ -0,0 +1,3 @@
1
+ import { TrackEvent, PerformanceType } from '@jolibox/types';
2
+ export declare const track: (event: TrackEvent, info: Record<string, unknown>) => void;
3
+ export declare const trackPerformance: (event: PerformanceType, duration: number, extra?: Record<string, unknown>) => void;
package/package.json CHANGED
@@ -1,39 +1,29 @@
1
1
  {
2
2
  "name": "@jolibox/sdk",
3
- "version": "0.0.8",
4
- "description": "Jolibox JavaScript SDK for Ads",
5
- "homepage": "https://sdk-docs.jolibox.com",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com:Jolibox-Developer/Jolibox-JS-SDK.git",
9
- "directory": "packages/ads"
10
- },
11
- "main": "dist/index.cjs",
12
- "type": "module",
13
- "module": "dist/index.js",
14
- "types": "dist/index.d.ts",
15
- "keywords": [
16
- "jolibox",
17
- "minigame",
18
- "sdk",
19
- "ads"
20
- ],
21
- "author": "Jolibox",
3
+ "description": "This project is common Jolibox JS-SDk interfere",
4
+ "version": "1.0.0-beta.0",
5
+ "main": "dist/index.cjs.js",
6
+ "module": "dist/index.es.js",
7
+ "typings": "dist/index.d.ts",
22
8
  "license": "MIT",
23
- "exports": {
24
- ".": {
25
- "types": "./dist/index.d.ts",
26
- "import": "./dist/index.js",
27
- "require": "./dist/index.cjs"
28
- }
29
- },
30
9
  "dependencies": {
31
- "@jolibox/web-sync-sdk": "0.0.8"
10
+ "@jolibox/common": "1.0.0-beta.0",
11
+ "@jolibox/types": "1.0.0-beta.0"
12
+ },
13
+ "devDependencies": {
14
+ "typescript": "5.7.3",
15
+ "@jolibox/eslint-config": "1.0.0",
16
+ "@types/jest": "28.1.1",
17
+ "rimraf": "6.0.1",
18
+ "esbuild": "0.24.2"
32
19
  },
33
20
  "scripts": {
34
- "build": "tsup",
35
- "typedoc": "typedoc",
36
- "typedoc:i18n": "typedoc --plugin typedoc-plugin-localization --generate-json ../../json/en",
37
- "test": "echo \"Error: no test specified\" && exit 1"
38
- }
21
+ "clean": "rimraf ./dist",
22
+ "build": "npm run clean && npm run build:cjs && npm run build:esm && tsc",
23
+ "build:cjs": "esbuild ./src/index.ts --log-level=error --format=cjs --outfile=./dist/index.cjs.js --bundle --minify",
24
+ "build:esm": "esbuild ./src/index.ts --log-level=error --format=esm --outfile=./dist/index.es.js --bundle --minify",
25
+ "dev": "tsc --watch",
26
+ "test": "jest"
27
+ },
28
+ "readme": "# Jolibox JSSDK Interface\n"
39
29
  }
package/sdk.build.log ADDED
@@ -0,0 +1,13 @@
1
+ Invoking: npm run clean && npm run build:cjs && npm run build:esm && tsc
2
+
3
+ > @jolibox/sdk@1.0.0-beta.0 clean
4
+ > rimraf ./dist
5
+
6
+
7
+ > @jolibox/sdk@1.0.0-beta.0 build:cjs
8
+ > esbuild ./src/index.ts --log-level=error --format=cjs --outfile=./dist/index.cjs.js --bundle --minify
9
+
10
+
11
+ > @jolibox/sdk@1.0.0-beta.0 build:esm
12
+ > esbuild ./src/index.ts --log-level=error --format=esm --outfile=./dist/index.es.js --bundle --minify
13
+
@@ -0,0 +1,76 @@
1
+ import { canIUse } from '../can-i-use';
2
+ import { env } from '../get-system-info';
3
+
4
+ jest.mock('../get-system-info');
5
+ jest.mock('../../utils/can-i-use', () => ({
6
+ //eslint-disable-next-line @typescript-eslint/ban-ts-comment
7
+ //@ts-ignore
8
+ ...jest.requireActual('../../utils/can-i-use'),
9
+ getCanIUseConfig: jest.fn()
10
+ }));
11
+
12
+ describe('canIUse', () => {
13
+ const mockEnv = env as jest.MockedFunction<typeof env>;
14
+ const mockGetCanIUseConfig = jest.requireMock('../../utils/can-i-use').getCanIUseConfig;
15
+
16
+ beforeEach(() => {
17
+ jest.clearAllMocks();
18
+ //eslint-disable-next-line @typescript-eslint/ban-ts-comment
19
+ //@ts-ignore
20
+ mockEnv.mockReturnValue({ data: { deviceInfo: { platform: 'h5' } } });
21
+ });
22
+
23
+ it('should return false when platform is not available', () => {
24
+ //eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
+ //@ts-ignore
26
+ mockEnv.mockReturnValue({ data: {} });
27
+ expect(canIUse('someApi')).toBe(false);
28
+ });
29
+
30
+ it('should return false when API config is not found', () => {
31
+ mockGetCanIUseConfig.mockReturnValue(null);
32
+ expect(canIUse('unknownApi')).toBe(false);
33
+ });
34
+
35
+ it('should return false when API version is invalid', () => {
36
+ mockGetCanIUseConfig.mockReturnValue({ version: {} });
37
+ expect(canIUse('api')).toBe(false);
38
+ });
39
+
40
+ it('should return true for supported API without properties', () => {
41
+ mockGetCanIUseConfig.mockReturnValue({ version: '0.9.0' });
42
+ expect(canIUse('supportedApi')).toBe(true);
43
+ });
44
+
45
+ it('should check H5 platform configuration', () => {
46
+ //eslint-disable-next-line @typescript-eslint/ban-ts-comment
47
+ //@ts-ignore
48
+ mockEnv.mockReturnValue({ data: { deviceInfo: { platform: 'h5' } } });
49
+ mockGetCanIUseConfig.mockReturnValue({ version: '0.9.0' });
50
+ expect(canIUse('webApi')).toBe(true);
51
+ expect(mockGetCanIUseConfig).toHaveBeenCalledWith('h5', 'webApi');
52
+ });
53
+
54
+ it('should handle nested property checks', () => {
55
+ mockGetCanIUseConfig.mockReturnValue({
56
+ version: '0.9.0',
57
+ properties: {
58
+ feature: {
59
+ subFeature: '0.9.0'
60
+ }
61
+ }
62
+ });
63
+
64
+ expect(canIUse('api:feature:subFeature')).toBe(true);
65
+ });
66
+
67
+ it('should return false for unsupported property version', () => {
68
+ mockGetCanIUseConfig.mockReturnValue({
69
+ version: '0.9.0',
70
+ properties: {
71
+ feature: '2.0.0'
72
+ }
73
+ });
74
+ expect(canIUse('api:feature')).toBe(false);
75
+ });
76
+ });
@@ -0,0 +1,38 @@
1
+ import { env as getEnv } from './get-system-info';
2
+ import { isObject, isString, compareVersion } from '@jolibox/common';
3
+ import { getCanIUseConfig, get } from '../utils/can-i-use';
4
+
5
+ const __VERSION__ = '1.0.0'; // mock
6
+
7
+ export function canIUse(schema: string): boolean {
8
+ const env = getEnv();
9
+ const platform = env.data?.deviceInfo?.platform;
10
+ if (!platform) {
11
+ return false;
12
+ }
13
+
14
+ const [name, ...rest] = schema.split(':');
15
+
16
+ const api = getCanIUseConfig(platform == 'h5' ? platform : 'native', name);
17
+
18
+ if (!api) return false;
19
+
20
+ const apiVersion = api['version'];
21
+
22
+ if (typeof apiVersion !== 'string') return false;
23
+
24
+ if (compareVersion(__VERSION__, apiVersion, '<')) return false;
25
+
26
+ if (rest.length === 0) return true;
27
+
28
+ return checkRest(api, rest) || checkRest(api['properties'], rest);
29
+ }
30
+
31
+ function checkRest(info: unknown, paths: string[]) {
32
+ if (!info) return false;
33
+ const v = get(info as Record<string, unknown>, paths);
34
+ if (!v) return false;
35
+ if (isObject(v)) return true;
36
+ if (isString(v)) return compareVersion(__VERSION__, v, '>=');
37
+ return false;
38
+ }
@@ -0,0 +1,14 @@
1
+ import { createCommands } from '@jolibox/common';
2
+
3
+ const commands = createCommands();
4
+ export async function getSystemInfo() {
5
+ return await commands.executeCommand('API.getSystemInfo');
6
+ }
7
+
8
+ export function getSystemInfoSync() {
9
+ return commands.excuteCommandSync('API.getSystemInfoSync');
10
+ }
11
+
12
+ export function env() {
13
+ return commands.excuteCommandSync('API.env');
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from './get-system-info';
2
+ export * from './can-i-use';
package/src/errors.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { hostEmitter, createCommands, BaseError } from '@jolibox/common';
2
+ document.addEventListener('DOMContentLoaded', () => hostEmitter.emit('onDocumentReady'));
3
+
4
+ const commands = createCommands();
5
+
6
+ const rejectHandler = (event: PromiseRejectionEvent | ErrorEvent | BaseError) => {
7
+ commands
8
+ .executeCommand('ReportSDK.traceSystem', {
9
+ event: 'global_js_error',
10
+ info: {
11
+ err: JSON.stringify(event)
12
+ }
13
+ })
14
+ .catch((e) => {
15
+ // 兜底上报
16
+ console.error(`Fallback report: ${e} ${JSON.stringify(event)}`);
17
+ });
18
+ };
19
+
20
+ export const reportError = rejectHandler;
21
+
22
+ window.addEventListener('unhandledrejection', rejectHandler.bind(this));
23
+ window.addEventListener('error', rejectHandler.bind(this));
24
+ window.onerror = (message, source, lineno, colno, error) => {
25
+ commands
26
+ .executeCommand('ReportSDK.traceSystem', {
27
+ event: 'global_js_error',
28
+ info: {
29
+ err: JSON.stringify({
30
+ message,
31
+ source,
32
+ lineno,
33
+ colno,
34
+ error
35
+ })
36
+ }
37
+ })
38
+ .catch((e) => {
39
+ // 兜底上报
40
+ console.error(`Fallback report: ${e} ${JSON.stringify(message)}`);
41
+ });
42
+ };
package/src/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ /** load implement at very first time */
2
+ /**
3
+ * global error catch
4
+ */
5
+ import './errors';
6
+ import './loader';
7
+
8
+ /**
9
+ * @public Jolibox JS SDK Entry
10
+ */
11
+ import { getSystemInfo, getSystemInfoSync, canIUse } from './api';
12
+ import { RuntimeSDK } from './sdks/runtime';
13
+ import { LifecycleSDK } from './sdks/lifecycle';
14
+ import { StorageSDK } from './sdks/storage';
15
+ import { JoliboxAds } from './sdks/ads';
16
+ import { KeyboardSDK } from './sdks/keyboard';
17
+
18
+ export class JoliboxSDK {
19
+ readonly runtime = new RuntimeSDK();
20
+ readonly ads = new JoliboxAds();
21
+ readonly lifecycle = new LifecycleSDK();
22
+ readonly storage = new StorageSDK();
23
+ readonly keyboard = new KeyboardSDK();
24
+
25
+ //global API
26
+ getSystemInfo = getSystemInfo.bind(this);
27
+ getSystemInfoSync = getSystemInfoSync.bind(this);
28
+ canIUse = canIUse.bind(this);
29
+ }
@@ -0,0 +1,175 @@
1
+ import { compare, major } from './version';
2
+ import { track, trackPerformance } from '../utils/report';
3
+ import { InternalJSModuleEvalError, InternalJSModuleFetchError } from '@jolibox/common';
4
+ import { getBoostrapModuleUrl, getImplementModuleUrl } from './index';
5
+ import { reportError } from '../errors';
6
+
7
+ const LOCAL_STORE_KEY = 'jolibox-sdk-loadermeta';
8
+ interface LocalStoreMeta {
9
+ bootstrap_version?: string;
10
+ bootstrap_script?: string;
11
+
12
+ implement_version?: string;
13
+ implement_script?: string;
14
+ timestamp?: number;
15
+ }
16
+
17
+ const CURRENT_VERSION_STORE: LocalStoreMeta = JSON.parse(localStorage.getItem(LOCAL_STORE_KEY) ?? '{}');
18
+ const now = Date.now();
19
+
20
+ const expired = (now: number, prev: number) =>
21
+ now > prev && Math.abs(now - prev) / (1000 * 60 * 60 * 24) >= 7;
22
+
23
+ const isLegalScript = (str: string) =>
24
+ !/^(Failed to fetch version|Couldn't find the requested file)/.test(str);
25
+ async function fetchCurrentRemoteScript() {
26
+ // TODO: adjust host
27
+ const path = `https://stg-api.jolibox.com/api/fe-configs/js-sdk/version_metadata`;
28
+ try {
29
+ const response = await fetch(path, {
30
+ method: 'GET',
31
+ headers: {
32
+ 'Content-Type': 'application/json'
33
+ }
34
+ });
35
+ const { implement_version, bootstrap_version }: LocalStoreMeta = await response.json();
36
+ let currentStore: LocalStoreMeta = { ...CURRENT_VERSION_STORE, timestamp: now };
37
+ if (bootstrap_version) {
38
+ const { bootstrap_version: currentLocalBootstrapVersion } = CURRENT_VERSION_STORE;
39
+ if (currentLocalBootstrapVersion && compare(currentLocalBootstrapVersion, bootstrap_version)) {
40
+ // no-op
41
+ } else {
42
+ const currentBootstrapModuleStr = await (await fetch(getBoostrapModuleUrl(bootstrap_version))).text();
43
+ isLegalScript(currentBootstrapModuleStr) &&
44
+ (currentStore = {
45
+ ...currentStore,
46
+ bootstrap_version,
47
+ bootstrap_script: currentBootstrapModuleStr
48
+ });
49
+ }
50
+ }
51
+ if (implement_version) {
52
+ const { implement_version: currentLocalImpelementVersion } = CURRENT_VERSION_STORE;
53
+ if (currentLocalImpelementVersion && compare(currentLocalImpelementVersion, implement_version)) {
54
+ // no-op
55
+ } else {
56
+ const currentImplementModuleStr = await (
57
+ await fetch(getImplementModuleUrl(implement_version))
58
+ ).text();
59
+ isLegalScript(currentImplementModuleStr) &&
60
+ (currentStore = {
61
+ ...currentStore,
62
+ implement_version,
63
+ implement_script: currentImplementModuleStr
64
+ });
65
+ }
66
+ }
67
+
68
+ localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(currentStore));
69
+ } catch (error) {
70
+ console.warn('Failed to fetch loader metadata: ', error);
71
+ }
72
+ }
73
+
74
+ export const createLoadImplement = (params: {
75
+ currentVersion: string;
76
+ currentMajorVersion: number;
77
+ bootstrapUrl: string;
78
+ implementUrl: string;
79
+ }) => {
80
+ const { currentMajorVersion, currentVersion, bootstrapUrl, implementUrl } = params;
81
+ function fetchCurrentBootstrapModule():
82
+ | { script: string; type: 'localscript' | 'fetch_from_cdn' }
83
+ | undefined {
84
+ const { bootstrap_version, bootstrap_script, timestamp } = CURRENT_VERSION_STORE;
85
+ if (bootstrap_version && bootstrap_script && timestamp) {
86
+ /**
87
+ * if current SDK major version is same && remote version is larget than current, use latest version
88
+ */
89
+ if (
90
+ !expired(now, timestamp) &&
91
+ major(bootstrap_version) == currentMajorVersion &&
92
+ compare(bootstrap_version, currentVersion) > 0
93
+ ) {
94
+ return { script: bootstrap_script, type: 'localscript' };
95
+ }
96
+ }
97
+ try {
98
+ const xhr = new XMLHttpRequest();
99
+ xhr.open('GET', bootstrapUrl, false);
100
+ xhr.send();
101
+ return { script: xhr.responseText, type: 'fetch_from_cdn' };
102
+ } catch (e) {
103
+ reportError(new InternalJSModuleFetchError(`Bootstrap module faile to fetch ${e}`));
104
+ }
105
+ }
106
+
107
+ function loadBootstrapModule() {
108
+ const startToLoad = Date.now();
109
+ track('js_sdk_begin', {
110
+ t: startToLoad
111
+ });
112
+
113
+ const { script: currentBootstrapModule, type } = fetchCurrentBootstrapModule() ?? {};
114
+ if (currentBootstrapModule) {
115
+ const script = document.createElement('script');
116
+ script.type = 'text/javascript';
117
+ script.innerHTML = currentBootstrapModule;
118
+ document.head.appendChild(script);
119
+ trackPerformance('bootstrapModuleLoaded', Date.now() - startToLoad, { type });
120
+ }
121
+ }
122
+
123
+ function evalLocalJSModule(code: string) {
124
+ const evalJS = async (code: string) => {
125
+ try {
126
+ const blob = new Blob([code], { type: 'application/javascript' });
127
+ const blobUrl = URL.createObjectURL(blob);
128
+ const module = await import(blobUrl);
129
+ URL.revokeObjectURL(blobUrl);
130
+ return module;
131
+ } catch (error) {
132
+ reportError(new InternalJSModuleEvalError(`implement module evaluate error in h5:${error} `));
133
+ }
134
+ };
135
+ evalJS(code);
136
+ }
137
+
138
+ // load remote impletation
139
+ function loadRemoteImplementation() {
140
+ const implStartLoad = Date.now();
141
+ const { implement_script, implement_version, timestamp } = CURRENT_VERSION_STORE;
142
+ if (implement_script && implement_version && timestamp) {
143
+ /**
144
+ * if current SDK major version is same && remote version is larget than current, use latest version
145
+ */
146
+ if (
147
+ !expired(now, timestamp) &&
148
+ major(implement_version) == currentMajorVersion &&
149
+ compare(implement_version, currentVersion) > 0
150
+ ) {
151
+ evalLocalJSModule(implement_script);
152
+ trackPerformance('implementModuleLoaded', Date.now() - implStartLoad, { type: 'loadscript' });
153
+ return;
154
+ }
155
+ }
156
+ const asyncScript = document.createElement('script');
157
+ asyncScript.type = 'module';
158
+ asyncScript.crossOrigin = 'anonymous';
159
+ asyncScript.src = implementUrl;
160
+ asyncScript.onload = () => {
161
+ trackPerformance('bootstrapModuleLoaded', Date.now() - implStartLoad, { type: 'fetch_from_cdn' });
162
+ };
163
+ document.head.appendChild(asyncScript);
164
+ }
165
+
166
+ return () => {
167
+ try {
168
+ loadBootstrapModule();
169
+ loadRemoteImplementation();
170
+ fetchCurrentRemoteScript();
171
+ } catch (e) {
172
+ reportError(new InternalJSModuleEvalError(`module evaluate error: ${e}`));
173
+ }
174
+ };
175
+ };