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.

534 lines (471 loc) • 15.7 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" ); 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); }; 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; };