2025-06-30 22:59:59 +00:00
|
|
|
import init, {ludus} from "./rudus.js";
|
2025-06-30 16:48:50 +00:00
|
|
|
|
2025-07-01 16:54:11 +00:00
|
|
|
let initialized_wasm = false
|
|
|
|
onmessage = run
|
2025-06-30 16:48:50 +00:00
|
|
|
|
2025-07-01 16:54:11 +00:00
|
|
|
// exposed in rust as:
|
|
|
|
// async fn io (out: String) -> Result<JsValue, JsValue>
|
|
|
|
// rust calls this to perform io
|
2025-06-30 16:48:50 +00:00
|
|
|
export function io (out) {
|
2025-07-01 16:54:11 +00:00
|
|
|
// only send messages if we have some
|
2025-06-30 22:59:59 +00:00
|
|
|
if (out.length > 0) postMessage(out)
|
2025-07-01 16:54:11 +00:00
|
|
|
// make an event handler that captures and delivers messages from the main thread
|
|
|
|
// because our promise resolution isn't about calculating a value but setting a global variable, we can't asyncify it
|
|
|
|
// explicitly return a promise
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
// deliver the response to ludus when we get a response from the main thread
|
2025-06-30 22:59:59 +00:00
|
|
|
onmessage = (e) => {
|
|
|
|
resolve(JSON.stringify(e.data))
|
|
|
|
}
|
2025-07-01 16:54:11 +00:00
|
|
|
// cancel the response if it takes too long
|
|
|
|
setTimeout(() => reject("io took too long"), 500)
|
2025-06-30 16:48:50 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2025-06-30 22:59:59 +00:00
|
|
|
|
2025-07-01 16:54:11 +00:00
|
|
|
// set as default event handler from main thread
|
2025-06-30 22:59:59 +00:00
|
|
|
async function run(e) {
|
2025-07-01 16:54:11 +00:00
|
|
|
// we must NEVER run `await init()` twice
|
|
|
|
if (!initialized_wasm) {
|
|
|
|
// this must come before the init call
|
|
|
|
initialized_wasm = true
|
2025-06-30 22:59:59 +00:00
|
|
|
await init()
|
2025-07-01 04:43:01 +00:00
|
|
|
console.log("Worker: Ludus has been initialized.")
|
2025-06-30 22:59:59 +00:00
|
|
|
}
|
2025-07-01 16:54:11 +00:00
|
|
|
// the data is always an array; we only really expect one member tho
|
2025-06-30 22:59:59 +00:00
|
|
|
let msgs = e.data
|
|
|
|
for (const msg of msgs) {
|
2025-07-01 16:54:11 +00:00
|
|
|
// evaluate source if we get some
|
2025-06-30 22:59:59 +00:00
|
|
|
if (msg.verb === "run" && typeof msg.data === 'string') {
|
2025-07-01 16:54:11 +00:00
|
|
|
// temporarily stash an empty function so we don't keep calling this one if we receive additional messages
|
2025-06-30 22:59:59 +00:00
|
|
|
onmessage = () => {}
|
2025-07-01 16:54:11 +00:00
|
|
|
// actually run the ludus--which will call `io`--and replace `run` as the event handler for ipc
|
2025-07-01 04:43:01 +00:00
|
|
|
await ludus(msg.data)
|
2025-07-01 16:54:11 +00:00
|
|
|
// once we've returned from `ludus`, make this the event handler again
|
2025-06-30 22:59:59 +00:00
|
|
|
onmessage = run
|
|
|
|
} else {
|
2025-07-01 16:54:11 +00:00
|
|
|
// report and swallow any malformed startup messages
|
2025-07-01 04:43:01 +00:00
|
|
|
console.log("Worker: Did not get valid startup message. Instead got:")
|
2025-06-30 22:59:59 +00:00
|
|
|
console.log(e.data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-06-30 16:48:50 +00:00
|
|
|
|
|
|
|
|