74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
import { run } from "@ludus/ludus-js-pure"
|
|
import { unlinkSync, readFileSync } from "node:fs"
|
|
|
|
export async function listen () {
|
|
const port = Math.floor((Math.random() * 1000) + 50000)
|
|
const session_token = crypto.randomUUID();
|
|
const repl_file_path = ".lrepl"
|
|
const repl_info = { port, session: session_token }
|
|
const repl_file = Bun.file(repl_file_path)
|
|
await Bun.write(repl_file, JSON.stringify(repl_info))
|
|
|
|
console.log(`Ludus REPL listening on localhost:${port}`)
|
|
console.log(`Session token: ${session_token}`)
|
|
|
|
Bun.listen({
|
|
hostname: "localhost",
|
|
port,
|
|
socket: {
|
|
data: (_, data) => {
|
|
const payload = data.toString("utf-8")
|
|
let session, source
|
|
try {
|
|
const json_msg = JSON.parse(payload)
|
|
session = json_msg.session
|
|
source = json_msg.source
|
|
} catch (e) {
|
|
console.log("Received malformed message.")
|
|
return
|
|
}
|
|
if (session !== session_token) {
|
|
console.log("Received message not from this REPL session.")
|
|
return
|
|
}
|
|
const result = run(source)
|
|
if (!result.errors) console.log("=>", result.result)
|
|
else {
|
|
console.log("Ludus had some errors:")
|
|
console.log(result.errors)
|
|
}
|
|
},
|
|
error: (socket, error) => { console.log(error); socket.end() }
|
|
}
|
|
})
|
|
|
|
|
|
process.on("exit", async function () {
|
|
try { cleanup(repl_file_path, session_token) } catch (e) {}
|
|
console.log("\nGoodbye.")
|
|
})
|
|
|
|
process.on("SIGINT", () => process.exit())
|
|
|
|
// Below here, I'm trying to get ctrl-d to work to close the listener
|
|
// the while (true) loop locks the listener
|
|
// see: https://github.com/oven-sh/bun/issues/3255
|
|
// this should be doable with process.stdin.on("close"...)
|
|
//const mystdin = Bun.file("/dev/stdin").stream().getReader()
|
|
|
|
// while (true) {
|
|
// const {done, value} = await mystdin.read()
|
|
// if (done) process.exit()
|
|
// console.log(value)
|
|
// }
|
|
|
|
}
|
|
|
|
// Don't delete an .lrepl we don't own
|
|
function cleanup (path: string, session_token: string) {
|
|
const repl_file = readFileSync(path).toString("utf-8")
|
|
const {session} = JSON.parse(repl_file)
|
|
if (session === session_token) unlinkSync(path)
|
|
}
|
|
|