UNPKG

@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 • 13.8 kB
export class XudaModule{constructor(e){this.func=e.func;this.glb=e.glb;this.SESSION_OBJ=e.SESSION_OBJ;this.SESSION_ID=e.SESSION_ID;this.APP_OBJ=e.APP_OBJ;this.dsSession=e.dsSession;this.job_id=e.job_id;this._session=this.SESSION_OBJ[this.SESSION_ID];return this}async get_field_value(field_id){if(!field_id){this.log("E","xu.getFieldValue","field_id cannot be empty",{code:"RUN_MSG_API_010"});return false}let ret_get_value=await this.func.datasource.get_value(this.SESSION_ID,field_id,this.dsSession);if(!ret_get_value.found){this.log("E","xu.getFieldValue",`${field_id} field not found`,{code:"RUN_MSG_API_020"});return false}return ret_get_value.ret.value}async set_field_value(field_id,value,avoid_refresh){if(!field_id){this.log("E","xu.setFieldValue","field_id cannot be empty",{code:"RUN_MSG_API_010"});return false}if(typeof value==="undefined"){this.log("E","xu.setFieldValue",`${field_id} - value cannot be undefined`,{code:"RUN_MSG_API_030"});return false}let ret_get_value=await this.func.datasource.get_value(this.SESSION_ID,field_id,this.dsSession);if(!ret_get_value.found){this.log("E","xu.setFieldValue",`${field_id} field not found`,{code:"RUN_MSG_API_020"});return false}let _ds=this._session.DS_GLB[ret_get_value.dsSessionP];const datasource_changes={[_ds.dsSession]:{[ret_get_value.currentRecordId]:{[field_id]:value}}};const refresh_options=avoid_refresh===true?{avoid_refresh:true,refresh_attributes:true}:avoid_refresh&&typeof avoid_refresh==="object"?avoid_refresh:{defer_refresh:true};if(avoid_refresh===true){try{globalThis.__XUDA_RT_TRACE&&console.log("[xuda-runtime] api_set_field_value_attributes_only "+JSON.stringify({field_id:field_id,dsSession:_ds.dsSession}))}catch(e){}}else if(!avoid_refresh){try{globalThis.__XUDA_RT_TRACE&&console.log("[xuda-runtime] api_set_field_value_deferred_refresh "+JSON.stringify({field_id:field_id,dsSession:_ds.dsSession}))}catch(e){}}return await this.func.datasource.update(this.SESSION_ID,datasource_changes,null,refresh_options)}async invoke_event(event_id,options){if(!event_id){this.log("E","xu.invokeEvent","event_id cannot be empty",{code:"RUN_MSG_API_040"});return false}const event_options=options&&typeof options==="object"?options:{avoid_refresh:options===true};let ds;for await(const[key,val]of Object.entries(Object.assign([],this._session.DS_GLB).reverse())){let ds_val=val;let ds_key=ds_val.dsSession;const _view_obj=await this.func.utils.VIEWS_OBJ.get(this.SESSION_ID,ds_val.prog_id);if(xu_isEmpty(_view_obj.progEvents))continue;if(ds)break;for await(const[key,val]of Object.entries(_view_obj.progEvents)){if(val?.data?.type==="user_defined"&&val.data.event_name===event_id){ds=ds_key;break}}}if(typeof ds==="undefined"){this.reject("xu.invokeEvent error",`${event_id} event_id not found`,this.job_id,{code:"RUN_MSG_API_050",source:"xu.invokeEvent"});return false}return this.func.events.validate(this.SESSION_ID,"user_defined",ds,event_id,null,null,null,event_options)}async read_drive(filename,cb){try{const response=await fetch(`https://${this._session.domain}/workspace-drive/`+filename+"&"+this._session.gtp_token);if(cb){return cb(await response.json())}return await response.json()}catch(e){this.reject("xu.readDrive error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.readDrive",err:e})}}async write_drive(stream,filename,make_public,cb){var data={app_id:this._session.app_id,gtp_token:this._session.gtp_token,app_token:this._session.app_token,req_from_api:"true",public:make_public?"true":""};const form=new FormData;for(const[key,val]of Object.entries(data)){form.append(key,val)}form.append("file",stream,filename);try{const response=await fetch(this.func.common.get_url(this.SESSION_ID,"rpi","runtime_upload_file"),{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(form)});if(cb){return cb(await response.json())}return await response.json()}catch(e){this.reject("xu.writeDrive error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.writeDrive",err:e})}}resolve(cb,job_id){if(job_id){this.func.events.delete_job(this.SESSION_ID,job_id)}if(cb){cb()}}reject(msg,details,job_id,meta={}){if(job_id){this.func.events.delete_job(this.SESSION_ID,job_id)}this.log("E",msg,details,meta)}log(type,msg,details,meta={}){const err=meta.err||(details instanceof Error?details:null);const message=typeof details==="undefined"?msg:details;if(this.func.utils.report_issue){return this.func.utils.report_issue(this.SESSION_ID,{code:meta.code,source:meta.source||msg,message:message,type:type,err:err,details:meta.details})}this.func.utils.debug_report(this.SESSION_ID,meta.source||msg,message,type,err,meta.details)}alert(type,display,msg,details){this.func.utils.alerts.execute(this.SESSION_ID,type,display,details,msg)}async call_project_api(prog_id,params,cb){const _prog_obj=await this.func.utils.DOCS_OBJ.get(this.SESSION_ID,prog_id);if(_prog_obj?.properties?.menuType!=="api"){return this.reject("xu.callApiProgram error",`${prog_id} is not an API program`,this.job_id)}if(this._session.engine_mode==="live_preview"||typeof IS_PROCESS_SERVER!=="undefined"){const ret=await this.func.datasource.prepare(this.SESSION_ID,prog_id,null,0,null,null,null,null,null,null,"api",null,null,null,params);try{const _ds=this._session.DS_GLB[ret.dsSessionP];if(typeof _ds.api_rendered_output==="undefined"||typeof _ds.tree_obj.apiOutput==="undefined"||!_ds.tree_obj.apiOutput){throw new Error("undefined api_rendered_output/apiOutput")}if(_ds.tree_obj.apiOutput==="json"){try{return JSON5.parse(_ds.api_rendered_output)}catch(err){this.log("E","xu.call_project_api",err,{code:"RUN_MSG_API_090",source:"xu.call_project_api",err:err});return{}}}return _ds.api_rendered_output}catch(e){this.reject("xu.call_project_api error",e.message||e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.call_project_api",err:e})}}if(["miniapp"].includes(this._session.engine_mode)){try{const response=await fetch(`https://${this._session.domain}/api`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({...params,...{prog_id:prog_id}})});if(cb){return cb(await response.json())}return await response.json()}catch(e){this.reject("xu.get_table_data error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.get_table_data",err:e})}}try{const response=await fetch(`https://${this._session.domain}/execute_api_program`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({...params,...{prog_id:prog_id}})});if(cb){return cb(await response.json())}return await response.json()}catch(e){this.reject("xu.get_table_data error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.get_table_data",err:e})}}async call_system_api(api_method,payload={},cb){try{let body={...{app_id:this._session.app_id,app_id_query:this._session.app_id,app_token:this._session.app_token},...payload};const response=await fetch(`https://${this._session.domain}/cpi/${api_method}`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(body)});const json=await response.json();if(cb){return cb(json)}return json}catch(e){this.reject("xu.call_system_api error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.call_system_api",err:e})}}async call_external_api(method,url,payload={},cb){try{let json={...{app_id:this._session.app_id,app_id_query:this._session.app_id,app_token:this._session.app_token},...payload};const response=await fetch(`https://${url}`,{method:method,headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(json)});if(cb){return cb(await response.json())}return await response.json()}catch(e){this.reject("xu.call_external_api error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.call_external_api",err:e})}}async call_javascript(prog_id,params={},evaluate=false){try{const module=await this.get_runtime_module_with_method("xuda-event-javascript-module.mjs","call_javascript");const result=await module.call_javascript(this.SESSION_ID,this.job_id,{prog:prog_id,parameters:params},this.dsSession,evaluate);return result}catch(e){this.reject("xu.call_javascript error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.call_javascript",err:e})}}async get_runtime_module_with_method(module_name,method_name){const load_module=async()=>{const module_ret=await this.func.common.get_module(this.SESSION_ID,module_name);if(typeof module_ret?.[method_name]==="function"){return module_ret}if(typeof module_ret?.default?.[method_name]==="function"){return module_ret.default}return module_ret};let module_ret=await load_module();if(typeof module_ret?.[method_name]==="function"){return module_ret}for(const key of Object.keys(this.func.common._import_cache||{})){if(key.includes(module_name)){delete this.func.common._import_cache[key]}}if(typeof globalThis!=="undefined"){globalThis.__XU_RUNTIME_MODULE_CACHE_TAG__=Date.now()}module_ret=await load_module();if(typeof module_ret?.[method_name]==="function"){return module_ret}throw new TypeError(`${module_name}.${method_name} is not available`)}async dbs_create(table_id,data,cb){const _table_obj=await this.func.utils.DOCS_OBJ.get(this.SESSION_ID,table_id);if(_table_obj?.properties?.menuType!=="table"){return this.reject("xu.dbsCreate error",`${table_id} is not a table`,this.job_id)}try{const ret=await this.func.common.db(this.SESSION_ID,"dbs_create",{table_id:table_id,table_data:data});if(cb){return cb(ret)}return ret}catch(e){this.reject("xu.dbs_create error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.dbs_create",err:e})}}async dbs_read(table_id,selector={},fields=[],sort,limit=999,skip,cb){const _table_obj=await this.func.utils.DOCS_OBJ.get(this.SESSION_ID,table_id);if(_table_obj?.properties?.menuType!=="table"){return this.reject("xu.dbsRead error",`${table_id} is not a table`,this.job_id)}const normalize_rows_response=function(ret){const rows=Array.isArray(ret)?ret:Array.isArray(ret?.rows)?ret.rows:Array.isArray(ret?.data?.rows)?ret.data.rows:[];Object.defineProperties(rows,{rows:{value:rows,enumerable:false,configurable:true},code:{value:ret?.code,enumerable:false,configurable:true},data:{value:ret?.data,enumerable:false,configurable:true},total_rows:{value:ret?.data?.total_rows??ret?.total_rows??rows.length,enumerable:false,configurable:true},response:{value:ret,enumerable:false,configurable:true}});return rows};let data={fields:fields,table_id:table_id,dataSourceFilterModelType:"query",filterModelMongo:typeof selector==="string"?selector:JSON.stringify(selector||{}),limit:limit,skip:skip,sort:sort};try{const ret=await this.func.common.db(this.SESSION_ID,"dbs_read",data);if(cb){return cb(ret)}return normalize_rows_response(ret)}catch(e){this.reject("xu.dbs_read error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.dbs_read",err:e})}}async dbs_update(table_id,row_id,data,cb){const _table_obj=await this.func.utils.DOCS_OBJ.get(this.SESSION_ID,table_id);if(_table_obj?.properties?.menuType!=="table"){return this.reject("xu.dbsUpdate error",`${table_id} is not a table`,this.job_id)}if(!row_id){return this.reject("xu.dbsDelete error",`row_id is a mandatory field`,this.job_id)}try{const ret=await this.func.common.db(this.SESSION_ID,"dbs_update",{table_id:table_id,row_id:row_id,table_data:data});if(cb){return cb(ret)}return ret}catch(e){this.reject("xu.dbs_update error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.dbs_update",err:e})}}async dbs_delete(table_id,row_id,cb){const _table_obj=await this.func.utils.DOCS_OBJ.get(this.SESSION_ID,table_id);if(_table_obj?.properties?.menuType!=="table"){return this.reject("xu.dbsDelete error",`${table_id} is not a table`,this.job_id)}if(!row_id){return this.reject("xu.dbsDelete error",`row_id is a mandatory field`,this.job_id)}try{const ret=await this.func.common.db(this.SESSION_ID,"dbs_delete",{table_id:table_id,ids:[row_id]});if(cb){return cb(ret)}return ret}catch(e){this.reject("xu.dbs_delete error",e,this.job_id,{code:"RUN_MSG_API_090",source:"xu.dbs_delete",err:e})}}}export const XU_SCRIPT_API={"xu.get_field_value(field_id)":"Read a field of the calling context (component/program dataset). Returns the value, or false + logged error when the field does not exist.","xu.set_field_value(field_id, value, avoid_refresh?)":"Write a field; the datasource updates and bound UI refreshes. This is how a script hands results back to the component.","xu.invoke_event(event_name, options?)":"Trigger a user_defined progEvents entry by its event_name.","xu.dbs_create(table_id, row_obj)":"Insert one row into a xuda table prog (menuType table). row_obj keys are the table field_ids. Returns {code, data}.","xu.dbs_read(table_id, selector?, fields?, sort?, limit?, skip?)":"Query a xuda table with a Mongo-style selector object ({} = all). Returns the rows ARRAY (default limit 999; rows also expose .total_rows).","xu.dbs_update(table_id, row_id, changes_obj)":"Update one row by its id.","xu.dbs_delete(table_id, row_id)":"Delete one row by its id.","xu.call_javascript(prog_id, params?, evaluate?)":"Run another javascript prog with parameters.","xu.call_project_api(prog_id, params?)":"Execute an api prog of this project and get its rendered output (parsed when the api outputs json).","xu.call_system_api(method, payload?)":"POST a platform cpi method (app_id/app_token are added automatically).","xu.call_external_api(method, url, payload?)":"HTTP request to an external host (url WITHOUT the https:// prefix).","xu.alert(type, display, message, details?)":"Show an alert - type: error|warn|info|log; display: console|modal|toast|browser.","xu.log(type, message, details?)":"Report to the runtime issue log (type E|W|I).","xu.read_drive(filename)":"Fetch a file from the app workspace drive (JSON-parsed).","xu.write_drive(stream, filename, make_public?)":"Upload a file to the app workspace drive."};