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.

484 lines (422 loc) • 15.3 kB
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 live_preview_loader = async function (SESSION_ID) { _this.glb.DEBUG_MODE = true; // $(_this.SESSION_OBJ[SESSION_ID].root_element).css( // "background-color", // "white" // ); // removed Aug 15,25 const ret = await init_studio_websocket(SESSION_ID); if (ret.error) { $(_session.root_element).show(); _this.func.UI.utils.progressScreen.show(SESSION_ID, 'Connection closed :(', null, true); throw 'Connection closed :('; } var data = ret.e; if (data.service === 'init_runtime_websocket') { await _this.func.UI.main.embed_loader(SESSION_ID); } else { var data = e; const call_embed = function () { _session.prog_id = data.data.id; console.log('call_embed', data.data.id); _this.func.UI.screen.call_embed(SESSION_ID, data.data.id); }; if (data.service === 'run_program_command') { if (_this.func.UI.utils.get_url_attribute(SESSION_ID, 'prog') || (typeof live_preview_getCookie !== 'undefined' && live_preview_getCookie('prog_id') && data.data.id !== live_preview_getCookie('prog_id') && live_preview_getCookie('gtp_prog_dynamic') === '0' && _this.func.utils.get_device())) return; // in case live preview is a program specific mode try { throw 'run new program, terminate prev execution'; } catch (ex) { call_embed(); } } if (data.service === 'debug_command') { _this.func.utils.debug.read_command(data.data); return; } } }; const init_studio_websocket = async function (SESSION_ID) { return new Promise(async function (resolve, reject) { var _session = _this.SESSION_OBJ[SESSION_ID]; var app_id = _session.app_id; const set_connected = async function (stat) { var datasource_changes = { [0]: { ['data_system']: { SYS_GLOBAL_BOL_CONNECTED: stat }, }, }; await func.datasource.update(SESSION_ID, datasource_changes); }; const peer_actions_module = await func.common.get_module(SESSION_ID, 'xuda-peer-actions-module.esm.js'); var preview_name = _session.url_params.preview_name || _session.opt.preview_name; // const peer = new Peer(); const connect_peer = function () { const peer = new Peer(SESSION_ID, { host: `${_session.domain}`, path: '/peer', secure: true, config: { iceServers: [ { urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:stun.l.google.com:5349' }, { urls: 'stun:stun1.l.google.com:3478' }, { urls: 'stun:stun1.l.google.com:5349' }, { urls: 'stun:stun2.l.google.com:19302' }, { urls: 'stun:stun2.l.google.com:5349' }, { urls: 'stun:stun3.l.google.com:3478' }, { urls: 'stun:stun3.l.google.com:5349' }, { urls: 'stun:stun4.l.google.com:19302' }, { urls: 'stun:stun4.l.google.com:5349' }, ], }, }); STUDIO_PEER = peer; peer.on('open', function (peer_id) { var peer_token = _session.gtp_token; const connect_peer = function () { if ($('.loader').length) { $('.loader_msg').html('Awaiting connection to Xuda Studio'); } const conn = peer.connect(peer_token, { metadata: { url_params: _session.url_params, client_info: _session.SYS_GLOBAL_OBJ_CLIENT_INFO, preview_name, user_info: _session.login_info, live_token_id: _session.opt.live_token_id, live_token_stat: _session.opt.live_token_stat, }, }); conn.on('open', (e) => { STUDIO_PEER_CONN_SEND_METHOD = conn.send.bind(conn); STUDIO_PEER_CONN_ID = conn.connectionId; set_connected(1); conn.on('data', (data) => { // console.log(data); if (data.service === 'auth' && data.data.live_token_stat === 2) { if (SESSION_OBJ[SESSION_ID].system_ready) { conn.send({ service: 'system_ready', // id: peer_id, }); if (STUDIO_PEER_CONN_MSG_QUEUE.length) { for (let val of STUDIO_PEER_CONN_MSG_QUEUE) { val.id = conn.connectionId; conn.send(val); } STUDIO_PEER_CONN_MSG_QUEUE = []; } } return connect_to_ws(peer_id); } peer_actions_module.peer_actions(SESSION_ID, STUDIO_PEER_CONN_SEND_METHOD, data); }); conn.on('error', (e) => { console.error('peer conn', e); }); conn.on('close', function (conn) { set_connected(0); $('body').removeClass('live_preview_online'); if (_session.opt.live_token_stat === 2) { func.UI.utils.progressScreen.show(SESSION_ID, 'Connection lost. Attempting to reconnect...', false, true); console.log('Connection lost. Attempting to reconnect...'); setTimeout(function () { // connect_peer(); location.reload(); }, 5000); // wait 5 seconds before trying to reconnect } }); }); conn.on('error', (e) => { console.error('peer conn', e); }); // TBD peer.on('call', function (call) { const displayMediaStreamConstraints = { video: { cursor: 'always', }, audio: true, preferCurrentTab: true, }; const success = function (stream) { call.answer(stream); }; const error = function (error) { call.answer(error); }; if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia(displayMediaStreamConstraints).then(success).catch(error); } else { navigator.getDisplayMedia(displayMediaStreamConstraints).then(success).catch(error); } // try { // navigator.mediaDevices // .getDisplayMedia( displayMediaStreamConstraints) // .then(function (stream) { // call.answer(stream); // Answer the call with an A/V stream. // }); // } catch (err) { // call.answer(); // } }); // connect_to_ws(peer_id); // temp to remove }; connect_peer(); }); peer.on('error', function (e) { if ($('.loader').length) { $('.loader_msg').html('Session has expired. Please renew the token session in Studio and reload.'); } }); // peer.on("call", function (call) { // const displayMediaStreamConstraints = { // video: { // cursor: "always", // }, // audio: true, // preferCurrentTab: true, // }; // const success = function (stream) { // call.answer(stream); // }; // const error = function (error) { // call.answer(error); // }; // if (navigator.mediaDevices.getDisplayMedia) { // navigator.mediaDevices // .getDisplayMedia(displayMediaStreamConstraints) // .then(success) // .catch(error); // } else { // navigator // .getDisplayMedia(displayMediaStreamConstraints) // .then(success) // .catch(error); // } // // try { // // navigator.mediaDevices // // .getDisplayMedia( displayMediaStreamConstraints) // // .then(function (stream) { // // call.answer(stream); // Answer the call with an A/V stream. // // }); // // } catch (err) { // // call.answer(); // // } // }); ///////////////////////////////// }; const broadcast_channel = function () { const channel = new BroadcastChannel(_session.gtp_token); STUDIO_PEER = channel; channel.onmessage = (event) => { if (event.data.session_id !== SESSION_ID) return; // if (event.data.service === "ping") { // return channel.postMessage({ // service: "pong", // session_id: SESSION_ID, // }); // } peer_actions_module.peer_actions(SESSION_ID, STUDIO_PEER_CONN_SEND_METHOD, event.data); }; channel.postMessage({ service: 'connection', metadata: { url_params: _session.url_params, client_info: _session.SYS_GLOBAL_OBJ_CLIENT_INFO, preview_name, user_info: _session.login_info, session_id: SESSION_ID, }, }); STUDIO_PEER_CONN_SEND_METHOD = channel.postMessage.bind(channel); set_connected(1); window.addEventListener('onCloseWindow', (event) => { console.log('onCloseWindow'); channel.postMessage({ service: 'disconnected', session_id: SESSION_ID, type: 'onCloseWindow', }); }); window.addEventListener('beforeunload', (event) => { console.log('beforeunload'); channel.postMessage({ service: 'disconnected', session_id: SESSION_ID, type: 'beforeunload', }); }); window.addEventListener('unload', (event) => { console.log('beforeunload'); channel.postMessage({ service: 'disconnected', session_id: SESSION_ID, type: 'unload', }); }); // return connect_to_ws(SESSION_ID); resolve({ e: { service: 'init_runtime_websocket' } }); }; const connect_to_ws = function (peer_id) { try { const url = 'https://' + _session.domain; STUDIO_WEBSOCKET = io(url, { secure: true, reconnection: _this.glb.debug_js ? false : true, // reconnectionDelay:10000, // reconnectionDelayMax: 30000, rejectUnauthorized: false, path: '/ws/socket.io', }); const ws_data = { service: 'init', id: peer_id, uid: _session.USR_OBJ._id, source: 'runtime', app_id: app_id, preview_name: preview_name, client_info: _session.SYS_GLOBAL_OBJ_CLIENT_INFO, session_id: SESSION_ID, gtp_token: _session.gtp_token, app_token: _session.app_token, }; STUDIO_WEBSOCKET.on('connect', () => { STUDIO_WEBSOCKET_CONNECTION_ID = STUDIO_WEBSOCKET.id; STUDIO_WEBSOCKET.emit('join-room', ws_data); resolve({ e: { service: 'init_runtime_websocket' } }); }); STUDIO_WEBSOCKET.on('studio-connected', (data) => { if (!data.reconnected) { STUDIO_WEBSOCKET.emit('init-studio', { ...ws_data, reconnected: true, }); } $(_session.root_element).addClass('live_preview_connected'); // $("body").addClass("live_preview_connected"); }); STUDIO_WEBSOCKET.on('user-disconnected', (data) => { $(_session.root_element).removeClass('live_preview_connected'); $(_session.root_element).removeClass('live_preview_online'); }); STUDIO_WEBSOCKET.on('disconnect', () => { console.log('disconnect', STUDIO_WEBSOCKET.id); // undefined }); STUDIO_WEBSOCKET.io.on('reconnect', (attempt) => { console.log('reconnect', attempt); }); } catch (e) { // connection to ws broken resolve(true); } }; if (_session.local_live_preview === 'true') { return broadcast_channel(); } connect_peer(); }); }; export const send_STUDIO_WEBSOCKET = function (SESSION_ID, service) { var _session = _this.SESSION_OBJ[SESSION_ID]; const data = { service: service, data: _session.USR_OBJ, id: STUDIO_PEER_CONN_ID, uid: _session.USR_OBJ._id, source: 'runtime', app_id: _session.app_id, gtp_token: _session.gtp_token, app_token: _session.app_token, }; if (!STUDIO_PEER_CONN_SEND_METHOD) { STUDIO_PEER_CONN_MSG_QUEUE.push(data); return; } STUDIO_PEER_CONN_SEND_METHOD(data); }; func.UI.screen.live_preview_hot_module_reload = async function (SESSION_ID, doc) { // const $elm = func.UI.utils.find_in_element_data( // "xuData", // $(SESSION_OBJ[SESSION_ID].root_element), // "prog_id", // doc._id // ); // console.log($elm); const $elm = func.UI.utils.find_in_element_data('xuPanelData', $(SESSION_OBJ[SESSION_ID].root_element), 'parent_element_ui_id'); var panels_obj = {}; if (!$elm.length) { // refresh screens for await (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB)) { if (val.prog_id === doc._id) { await func.action.execute(SESSION_ID, 'act_reload', val); break; } } return; } // refresh panels for await (const [elem_key, elem_val] of Object.entries($elm)) { if (elem_key === 'length') break; var $div = $(elem_val); let xuData = $div.data().xuData; if (!$div.data().xuPanelData) continue; let dsSession = xuData.paramsP.dsSessionP; var _session = SESSION_OBJ[SESSION_ID]; let _ds = _session?.DS_GLB[dsSession]; if (!_ds) continue; if (_ds.prog_id !== doc._id) { continue; } const parent_element_ui_id = $div.data().xuPanelData.parent_element_ui_id; if (!panels_obj[parent_element_ui_id]) { panels_obj[parent_element_ui_id] = { _ds, $div, ids: [], }; } panels_obj[parent_element_ui_id].ids.push($div.attr('xu-ui-id')); } for await (const [parent_element_ui_id, panel_val] of Object.entries(panels_obj)) { var $div_elm = panel_val.$div .parent() .parent() .find("[xu-ui-id='" + parent_element_ui_id + "']"); // restore original panel try { const $org_panel = panel_val.$div.data().xuPanelData.$panel_div; //panel_val.$div.clone(true); const new_$div = await func.UI.screen.render_ui_tree( SESSION_ID, $div_elm, _.cloneDeep(panel_val.$div.data().xuPanelData.node), {}, $org_panel.data().xuData.paramsP, null, null, $org_panel.data().xuData.key, null, $org_panel.data().xuData.parent_node, null, $org_panel.data().xuData.$root_container, ); // remove old panel content $.each(panel_val.ids, async function (key, val) { $("[xu-ui-id='" + val + "']").remove(); }); } catch (error) { debugger; } } return panels_obj; };