framerock/frontend/index.js

98 lines
2.3 KiB
JavaScript

// 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)
this.transport_send_bytes = this._transport_send_bytes.bind(this)
return
}
_setup_transport ({ on_open, on_close, on_message }) {
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 = (event) => {
console.info('WS MESSAGE', event)
if (on_message !== undefined) {
on_message(event.data)
}
else {
console.warn(['Unhandled message', event])
}
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
}
_transport_send_bytes (msg_bytes) {
const ws = this._ws
if (ws.readyState === WebSocket.OPEN) {
ws.send(msg_bytes)
}
else {
console.warn('ws readyState !== OPEN : dropping event send')
}
return
}
}
const FRAMEROCK_UTILS = new FramerockUtils()
do_safereval_strscript({ FRAMEROCK_UTILS }, JS_APP_FRONTEND)