// provided by outer context: APP_CONSTANTS, JS_APP_FRONTEND const setup_safer_eval = function (lst_idents) { const runCodeWithCustomFunction = (obj) => { return Function(...lst_idents.map(x=>x[0]), `"use strict";return (${obj});`.trim())(...lst_idents.map(x=>x[1])) } return runCodeWithCustomFunction } const do_safereval_strscript = function (obj_eval_defines, the_strscript) { const lst_idents = Object.entries(obj_eval_defines).map(([k,v])=>[k,v]).toSorted((a,b)=>(a[0]-b[0])) const the_eval_func = setup_safer_eval(lst_idents) const the_eval_result = the_eval_func(` (function(){ ${the_strscript} return })() `.trim()) return the_eval_result } class FramerockUtils { constructor () { this._ws = undefined this.setup_transport = this._setup_transport.bind(this) this.teardown_transport = this._teardown_transport.bind(this) return } _setup_transport ({ on_open, on_close }) { console.info('SETUP TRANSPORT') this._ws = new WebSocket(`ws://${window.location.host}/ws`) const ws = this._ws ws.binaryType = 'arraybuffer' const func_on_open = () => { console.info('WS OPEN') on_open && on_open() return } const func_on_close = (event) => { console.info('WS CLOSE') on_close && on_close(event) return } const func_on_message = (e) => { console.info('WS MESSAGE') return } const func_on_error = () => { console.info('WS ERROR') return } ws.addEventListener('open' , func_on_open) ws.addEventListener('close' , func_on_close) ws.addEventListener('message', func_on_message) ws.addEventListener('error' , func_on_error) return } _teardown_transport () { console.info('TEARDOWN TRANSPORT') // NOTE: has no effect if ws already closed this._ws.close() return } } const FRAMEROCK_UTILS = new FramerockUtils() do_safereval_strscript({ FRAMEROCK_UTILS }, JS_APP_FRONTEND)