@xuda.io/runtime-bundle
Version:
The Xuda Runtime Bundle refers to a collection of scripts and libraries packaged together to provide the necessary runtime environment for executing plugins or components in the Xuda platform.
1 lines • 9.79 kB
JavaScript
const _this={};export const init_module=e=>{_this.func=e.func;_this.glb=e.glb;_this.SESSION_OBJ=e.SESSION_OBJ;_this.APP_OBJ=e.APP_OBJ;_this.IS_DOCKER=e.IS_DOCKER;_this.IS_API_SERVER=e.IS_API_SERVER;_this.IS_PROCESS_SERVER=e.IS_PROCESS_SERVER};export const get_doc_from_studio=async function(SESSION_ID,app_id,idP){return new Promise(function(resolve,reject){var _session=_this.SESSION_OBJ[SESSION_ID];if(glb.IS_WORKER){func.utils.post_back_to_client(SESSION_ID,"get_doc_from_studio",_session.worker_id,{doc_id:idP});self.addEventListener("live_preview_get_obj_response_worker_"+idP,event=>{resolve(event.detail.data)})}else{STUDIO_PEER_CONN_SEND_METHOD({service:"get_doc_obj",data:{doc_id:idP},session_id:SESSION_ID,id:STUDIO_PEER.id,source:"runtime",app_id:app_id});const _lp_handler=function(data){resolve(data.data);func.runtime.platform.off("live_preview_get_obj_response_"+idP,_lp_handler)};func.runtime.platform.on("live_preview_get_obj_response_"+idP,_lp_handler)}})};export const get_doc_from_websocket=async function(SESSION_ID,app_id,idP){var _session=_this.SESSION_OBJ[SESSION_ID];return new Promise(function(resolve,reject){let done=false;let cleanup=function(){};const finish=function(err,data){if(done)return;done=true;clearTimeout(timeout);cleanup();if(err){reject(err);return}resolve(data)};const timeout=setTimeout(()=>{finish(new Error(`get_doc_from_websocket timeout: ${idP}`))},8e3);if(glb.IS_WORKER){func.utils.post_back_to_client(SESSION_ID,"get_doc_from_websocket",_session.worker_id,{doc_id:idP});const worker_event="get_doc_obj_from_build_worker_"+idP;const worker_handler=event=>{finish(null,event.detail.data)};cleanup=function(){self.removeEventListener?.(worker_event,worker_handler)};self.addEventListener(worker_event,worker_handler)}else{if(RUNTIME_SERVER_WEBSOCKET&&RUNTIME_SERVER_WEBSOCKET_CONNECTED){const ws_event="get_doc_obj_from_build_response_"+idP;const _doc_handler=function(data){finish(null,data.data)};cleanup=function(){func.runtime.platform.off(ws_event,_doc_handler)};func.runtime.platform.on(ws_event,_doc_handler);RUNTIME_SERVER_WEBSOCKET.emit("message",{service:"get_doc_obj_from_build",data:{doc_id:idP}})}else{finish(new Error("fail to fetch from ws websocket inactive"))}}})};const should_fallback_doc_http=function(err){const message=`${err?.message||err||""}`;return/websocket inactive|get_doc_from_websocket timeout/i.test(message)};const warn_doc_http_fallback=function(SESSION_ID,app_id,idP,err){const _session=_this.SESSION_OBJ[SESSION_ID];_session.doc_http_fallback_count=(_session.doc_http_fallback_count||0)+1;if(_session.doc_http_fallback_warned){return}_session.doc_http_fallback_warned=true;console.warn("[xuda-runtime] doc_ws_fallback_http",{app_id:app_id,doc_id:idP,reason:err?.message||String(err||""),note:"subsequent document websocket fallbacks are counted on SESSION_OBJ[SESSION_ID].doc_http_fallback_count"})};const get_doc_from_studio_with_timeout=async function(SESSION_ID,app_id,idP,timeout_ms=5e3){return new Promise(resolve=>{let resolved=false;const timeout=setTimeout(()=>{if(resolved)return;resolved=true;resolve(null)},timeout_ms);get_doc_from_studio(SESSION_ID,app_id,idP).then(doc=>{if(resolved)return;resolved=true;clearTimeout(timeout);resolve(doc)}).catch(()=>{if(resolved)return;resolved=true;clearTimeout(timeout);resolve(null)})})};const get_doc_from_runtime_http=async function(SESSION_ID,app_id,idP){const _session=_this.SESSION_OBJ[SESSION_ID];let url=_this.func.common.get_url(SESSION_ID,"rpi","");if(["master"].includes(_this.APP_OBJ[app_id]?.app_type)){url+="get_doc_obj_raw"}else{url+="get_doc_obj_from_build"}const response=await fetch(url,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","xu-gtp-token":_session.gtp_token,"xu-app-token":_session.app_token},body:JSON.stringify({app_id:app_id,doc_id:idP,build:_session.build_info?.instance_build||_session.build_info?.build||_session.opt.app_build_id,app_id_reference:_this.APP_OBJ[app_id]?.app_id_reference,engine_mode:_session.engine_mode})});if(!response.ok){if(response.status===400){return _this.func.utils.request_error(SESSION_ID,"ajax",response.statusText)}throw new Error(await response.text())}const json=await response.json();return json.data};const get_doc_from_runtime_cache_or_remote=async function(SESSION_ID,app_id,idP,obj_type="DOCS_OBJ"){const _session=_this.SESSION_OBJ[SESSION_ID];let views_ret=await read_objects_cache(SESSION_ID,idP,obj_type);if(!views_ret){if(typeof _this.IS_DOCKER==="undefined"&&typeof _this.IS_PROCESS_SERVER==="undefined"){if(_session.engine_mode==="miniapp"||_session.engine_mode==="live_preview"){views_ret=await get_doc_from_runtime_http(SESSION_ID,app_id,idP)}else{try{views_ret=await get_doc_from_websocket(SESSION_ID,app_id,idP)}catch(err){if(!should_fallback_doc_http(err)){throw err}warn_doc_http_fallback(SESSION_ID,app_id,idP,err);views_ret=await get_doc_from_runtime_http(SESSION_ID,app_id,idP)}}}if(typeof _this.IS_DOCKER!=="undefined"||typeof _this.IS_PROCESS_SERVER!=="undefined"){const ret=await __.rpi.get_prog(app_id,idP);if(ret.data){views_ret=ret.data}}if(views_ret){if(views_ret.error){console.error(views_ret);return}await save_objects_cache(SESSION_ID,idP,obj_type,views_ret)}}return views_ret};export const DOCS_OBJ_get=async function(SESSION_ID,idP){if(!idP)return;if(idP==="_empty_panel_program"){return{_id:"_empty_panel_program",properties:{menuName:"_empty_panel_program",menuTitle:"_empty_panel_program",menuType:"component",renderType:"form"},progUi:[{id:"node-empty_panel_program",tagName:"xu-single-view",children:[{id:"node-empty_panel_program-span",tagName:"span",children:[],content:"",type:"element",attributes:{}}],content:"",type:"element",attributes:{}}],progDataSource:{},progFields:[],progEvents:[]}}var _session=_this.SESSION_OBJ[SESSION_ID];const app_id=_session.app_id;var views_ret;if(_session.engine_mode==="live_preview"){if(_session.is_draft_runtime){return await get_doc_from_studio(SESSION_ID,app_id,idP)}if(!_session.live_preview_studio_doc_source_unavailable){views_ret=await get_doc_from_studio_with_timeout(SESSION_ID,app_id,idP);if(views_ret){return views_ret}_session.live_preview_studio_doc_source_unavailable=true}return await get_doc_from_runtime_cache_or_remote(SESSION_ID,app_id,idP)}if(glb.register_startup_programs){func.common.db(SESSION_ID,"register_startup_programs",{prog_id:idP,build_id:_session?.build_info?.build||0})}return await get_doc_from_runtime_cache_or_remote(SESSION_ID,app_id,idP)};export const save_objects_cache=async function(SESSION_ID,id,obj_type,data){var _session=_this.SESSION_OBJ[SESSION_ID];if(typeof _this.IS_DOCKER!=="undefined"||typeof _this.IS_PROCESS_SERVER!=="undefined"||_session.worker_type==="Dev"){return}var build_id=_session?.build_info?.build||0;const db=await _this.func.utils.connect_pouchdb(SESSION_ID);var doc={_id:`cache_${build_id}_${obj_type}_${id}`,id:id,docType:"cache_objects",build_id:build_id.toString(),obj_type:obj_type,data:data};setTimeout(async function(){try{await db.get(doc_id);return}catch(e){if(await read_objects_cache(SESSION_ID,id,obj_type)){return}if(!doc.data||doc.data&&typeof doc.data==="string"&&doc.data.indexOf("error")>-1){return}try{return await db.put(doc)}catch(err){return}}},1e3)};export const read_objects_cache=async function(SESSION_ID,id,obj_type){if(typeof _this.IS_DOCKER!=="undefined"||typeof _this.IS_PROCESS_SERVER!=="undefined"){try{const data=fs.readFileSync("/var/xuda/progs/"+id+".json","utf8");return JSON.parse(data)}catch(err){console.error("read_objects_cache",err);return}}var _session=_this.SESSION_OBJ[SESSION_ID];var build_id=_session?.build_info?.build||0;const db=await _this.func.utils.connect_pouchdb(SESSION_ID);var ret;try{ret=await db.get(`cache_${build_id}_${obj_type}_${id}`);if(ret.data&&typeof ret.data==="string"&&ret.data.indexOf("error")>-1){return""}return ret.data}catch(err){return ret}};export const delete_objects_cache=async function(SESSION_ID,id,obj_type){const app_id=_this.SESSION_OBJ[SESSION_ID].app_id;var build_id=_session?.build_info?.build||0;const db=await _this.func.utils.connect_pouchdb(SESSION_ID);try{var doc=await db.get(`cache_${build_id}_${obj_type}_${id}`);if(!doc)return;var ret=await db.remove(doc)}catch(err){return}return ret};export const load_objects_cache=async function(SESSION_ID){var _session=_this.SESSION_OBJ[SESSION_ID];if(typeof _this.IS_DOCKER!=="undefined"||typeof _this.IS_PROCESS_SERVER!=="undefined"){return}const app_id=_session.app_id;const db=await _this.func.utils.connect_pouchdb(SESSION_ID);const build_id=_this.APP_OBJ[app_id].app_build_id;let ret=await db.find({selector:{docType:"cache_objects",build_id:build_id}});for(let val of ret.docs){eval(val.obj_type)[_session.app_id][val.id]=val.data}};export const prime_objects_cache=async function(SESSION_ID,obj_type,data_by_id={}){var _session=_this.SESSION_OBJ[SESSION_ID];if(typeof _this.IS_DOCKER!=="undefined"||typeof _this.IS_PROCESS_SERVER!=="undefined"||_session.worker_type==="Dev"){return}const ids=Object.keys(data_by_id||{});if(!ids.length){return}const build_id=(_session?.build_info?.build||0).toString();const db=await _this.func.utils.connect_pouchdb(SESSION_ID);const cache_doc_ids=ids.map(id=>`cache_${build_id}_${obj_type}_${id}`);const existing_docs=await db.allDocs({keys:cache_doc_ids});const existing_revs={};for(const row of existing_docs.rows||[]){if(row?.value?.rev){existing_revs[row.id]=row.value.rev}}const docs=ids.map(id=>{const cache_id=`cache_${build_id}_${obj_type}_${id}`;const doc={_id:cache_id,id:id,docType:"cache_objects",build_id:build_id,obj_type:obj_type,data:data_by_id[id]};if(existing_revs[cache_id]){doc._rev=existing_revs[cache_id]}return doc});await db.bulkDocs(docs);for(const id of ids){eval(obj_type)[_session.app_id][id]=data_by_id[id]}};