initial commit 🎭
This commit is contained in:
commit
6a4a0a2c28
3 changed files with 171 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
bun.lock
|
9
package.json
Normal file
9
package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "stage_d",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "src/index.js",
|
||||
"dependencies": {
|
||||
"framerock": "git+https://git.daemons.my/dab/framerock.git#7c46e53d086af1b5093d308df5b52e88cb666e8d"
|
||||
}
|
||||
}
|
160
src/index.js
Normal file
160
src/index.js
Normal file
|
@ -0,0 +1,160 @@
|
|||
import { isAsyncFunction } from 'node:util/types'
|
||||
import { async_run } from 'framerock'
|
||||
|
||||
function bytesToBase64 (bytes) {
|
||||
return btoa(Array.from(bytes, function (byte) {return String.fromCodePoint(byte);}).join(''))
|
||||
}
|
||||
|
||||
const async_stage = async function (role_defs, { framerock_config }) {
|
||||
|
||||
const jsbuild_app_frontend = async function () {
|
||||
const page_params = bytesToBase64(new TextEncoder().encode(JSON.stringify({ role_keys: [ ...Object.keys(role_defs) ] })))
|
||||
return `
|
||||
function base64ToBytes (base64) {
|
||||
return Uint8Array.from(atob(base64), function (m) {return m.codePointAt(0);})
|
||||
}
|
||||
|
||||
const page_params = JSON.parse(new TextDecoder().decode(base64ToBytes("${page_params}")))
|
||||
|
||||
const result_handlers = new Map()
|
||||
|
||||
const setup_dom = function () {
|
||||
|
||||
document.head.insertAdjacentHTML('beforeend', '<style type="text/css">html, body{ height: 100%; width: 100%; margin: 0px; padding: 0px; overflow: hidden;}</style>')
|
||||
const elem_root = document.createElement('div')
|
||||
elem_root.style = 'height: 100%; width: 100%; font-family: sans-serif; position: relative; font-size: 16px;'
|
||||
|
||||
const elem_topbar = document.createElement('div')
|
||||
elem_topbar.style = 'height: 100px; background-color: #333; color: #FFF; display: flex; align-items: center; overflow: hidden;'
|
||||
|
||||
const elem_title = document.createElement('div')
|
||||
elem_title.style = 'font-size: 32px; font-weight: bold; user-select: none; margin-left: 32px;'
|
||||
elem_title.textContent = 'stage_d'
|
||||
|
||||
const elem_view = document.createElement('div')
|
||||
elem_view.style = 'position: absolute; top: 100px; left: 0px; right: 0px; bottom: 0px; background-color: #000; color: #FFF; overflow: auto;'
|
||||
|
||||
const elems_roledefs = page_params.role_keys.map((role_key) => {
|
||||
const elem_role = document.createElement('div')
|
||||
elem_role.style = 'border: 1px solid #FFF; padding: 10px; box-sizing: border-box;'
|
||||
|
||||
const elem_roletitle = document.createElement('div')
|
||||
elem_roletitle.textContent = role_key
|
||||
|
||||
const elem_results = document.createElement('div')
|
||||
elem_results.style = 'max-height: 200px; overflow: auto; font-family: monospace; font-size: 14px;'
|
||||
|
||||
const elem_btninitcue = document.createElement('button')
|
||||
elem_btninitcue.textContent = 'initiate cue'
|
||||
const func_click_rolecue = () => {
|
||||
elem_btninitcue.disabled = true
|
||||
initiate_cue_handle_result(role_key, { foo: 'bar' }, (result_obj) => {
|
||||
elem_btninitcue.disabled = false
|
||||
const elem_resultrow = document.createElement('div')
|
||||
elem_resultrow.style = 'border: 1px solid blue; padding: 10px; box-sizing: border-box;'
|
||||
elem_resultrow.textContent = JSON.stringify(result_obj)
|
||||
elem_results.appendChild(elem_resultrow)
|
||||
return
|
||||
})
|
||||
return
|
||||
}
|
||||
elem_btninitcue.addEventListener('click', func_click_rolecue)
|
||||
|
||||
elem_role.appendChild(elem_roletitle)
|
||||
elem_role.appendChild(elem_btninitcue)
|
||||
elem_role.appendChild(elem_results)
|
||||
|
||||
return elem_role
|
||||
})
|
||||
|
||||
elem_topbar.appendChild(elem_title)
|
||||
elems_roledefs.forEach((elem)=>elem_view.appendChild(elem))
|
||||
|
||||
elem_root.appendChild(elem_topbar)
|
||||
elem_root.appendChild(elem_view)
|
||||
|
||||
document.body.appendChild(elem_root)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const initiate_cue_handle_result = function (role_key, payload, func_onresult) {
|
||||
const uid = crypto.randomUUID()
|
||||
result_handlers.set(uid, func_onresult)
|
||||
FRAMEROCK_UTILS.transport_send_bytes(new TextEncoder().encode(JSON.stringify([ 'HANDLE_CUE_INIT', { uid, role_key, payload } ])))
|
||||
return
|
||||
}
|
||||
|
||||
const on_open = function () {
|
||||
return
|
||||
}
|
||||
const on_message = function (event) {
|
||||
const [ evt_type, evt_data ] = JSON.parse(new TextDecoder().decode(event.data))
|
||||
if (evt_type === 'HANDLE_CUE_RESULT') {
|
||||
const [ uid, result_obj ] = evt_data
|
||||
const func_onresult = result_handlers.get(uid)
|
||||
if (func_onresult === undefined) {
|
||||
console.error(['Unexpected: func_onresult is undefined', { uid }])
|
||||
}
|
||||
else {
|
||||
result_handlers.delete(uid)
|
||||
func_onresult(result_obj)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
setup_dom()
|
||||
FRAMEROCK_UTILS.setup_transport({ on_open, on_message })
|
||||
`.trim()
|
||||
}
|
||||
|
||||
const handle_transport_bytes = function (utils, message) {
|
||||
const [ evt_type, evt_data ] = JSON.parse(new TextDecoder().decode(message))
|
||||
if (evt_type === 'HANDLE_CUE_INIT') {
|
||||
const { uid, role_key, payload } = evt_data
|
||||
const send_result = (result_obj) => {
|
||||
utils.transport_send_bytes(new TextEncoder().encode(JSON.stringify([ 'HANDLE_CUE_RESULT', [ uid, result_obj ] ])))
|
||||
return
|
||||
}
|
||||
const on_cue = role_defs[role_key]
|
||||
if (on_cue === undefined) {
|
||||
console.error(['Unexpected: on_cue is undefined', { role_key }])
|
||||
}
|
||||
else {
|
||||
if (isAsyncFunction(on_cue)) {
|
||||
on_cue(payload).then((result_complete) => {
|
||||
send_result({ result_complete })
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
send_result({ result_error: true })
|
||||
})
|
||||
}
|
||||
else {
|
||||
let result_complete
|
||||
let did_error = false
|
||||
try {
|
||||
result_complete = on_cue(payload)
|
||||
}
|
||||
catch (err) {
|
||||
did_error = true
|
||||
console.error(err)
|
||||
}
|
||||
if (did_error === false) {
|
||||
send_result({ result_complete })
|
||||
}
|
||||
else {
|
||||
send_result({ result_error: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
await async_run({ config: framerock_config, jsbuild_app_frontend, handle_transport_bytes })
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
export { async_stage }
|
Loading…
Add table
Reference in a new issue